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 
43 #include <blaze/math/Aliases.h>
47 #include <blaze/math/Functions.h>
49 #include <blaze/math/shims/Equal.h>
51 #include <blaze/math/shims/IsNaN.h>
52 #include <blaze/math/shims/IsOne.h>
69 #include <blaze/util/Assert.h>
70 #include <blaze/util/FalseType.h>
71 #include <blaze/util/mpl/If.h>
72 #include <blaze/util/TrueType.h>
73 #include <blaze/util/Types.h>
75 
76 
77 namespace blaze {
78 
79 //=================================================================================================
80 //
81 // GLOBAL OPERATORS
82 //
83 //=================================================================================================
84 
85 //*************************************************************************************************
88 template< typename T1, typename T2, bool SO >
89 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs );
90 
91 template< typename T1, typename T2, bool SO >
92 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs );
93 
94 template< typename T1, typename T2, bool SO >
95 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs );
96 
97 template< typename T1, bool SO1, typename T2, bool SO2 >
98 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs );
100 //*************************************************************************************************
101 
102 
103 //*************************************************************************************************
111 template< typename T1 // Type of the left-hand side sparse matrix
112  , typename T2 > // Type of the right-hand side sparse matrix
113 inline bool operator==( const SparseMatrix<T1,false>& lhs, const SparseMatrix<T2,false>& rhs )
114 {
115  typedef CompositeType_<T1> CT1;
116  typedef CompositeType_<T2> CT2;
117  typedef ConstIterator_< RemoveReference_<CT1> > LhsConstIterator;
118  typedef ConstIterator_< RemoveReference_<CT2> > RhsConstIterator;
119 
120  // Early exit in case the matrix sizes don't match
121  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
122  return false;
123 
124  // Evaluation of the two sparse matrix operands
125  CT1 A( ~lhs );
126  CT2 B( ~rhs );
127 
128  // In order to compare the two matrices, the data values of the lower-order data
129  // type are converted to the higher-order data type within the equal function.
130  for( size_t i=0UL; i<A.rows(); ++i )
131  {
132  const LhsConstIterator lend( A.end(i) );
133  const RhsConstIterator rend( B.end(i) );
134 
135  LhsConstIterator lelem( A.begin(i) );
136  RhsConstIterator relem( B.begin(i) );
137 
138  while( lelem != lend && relem != rend )
139  {
140  if( lelem->index() < relem->index() ) {
141  if( !isDefault( lelem->value() ) )
142  return false;
143  ++lelem;
144  }
145  else if( lelem->index() > relem->index() ) {
146  if( !isDefault( relem->value() ) )
147  return false;
148  ++relem;
149  }
150  else if( !equal( lelem->value(), relem->value() ) ) {
151  return false;
152  }
153  else {
154  ++lelem;
155  ++relem;
156  }
157  }
158 
159  while( lelem != lend ) {
160  if( !isDefault( lelem->value() ) )
161  return false;
162  ++lelem;
163  }
164 
165  while( relem != rend ) {
166  if( !isDefault( relem->value() ) )
167  return false;
168  ++relem;
169  }
170  }
171 
172  return true;
173 }
174 //*************************************************************************************************
175 
176 
177 //*************************************************************************************************
185 template< typename T1 // Type of the left-hand side sparse matrix
186  , typename T2 > // Type of the right-hand side sparse matrix
187 inline bool operator==( const SparseMatrix<T1,true>& lhs, const SparseMatrix<T2,true>& rhs )
188 {
189  typedef CompositeType_<T1> CT1;
190  typedef CompositeType_<T2> CT2;
191  typedef ConstIterator_< RemoveReference_<CT1> > LhsConstIterator;
192  typedef ConstIterator_< RemoveReference_<CT2> > RhsConstIterator;
193 
194  // Early exit in case the matrix sizes don't match
195  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() )
196  return false;
197 
198  // Evaluation of the two sparse matrix operands
199  CT1 A( ~lhs );
200  CT2 B( ~rhs );
201 
202  // In order to compare the two matrices, the data values of the lower-order data
203  // type are converted to the higher-order data type within the equal function.
204  for( size_t j=0UL; j<A.columns(); ++j )
205  {
206  const LhsConstIterator lend( A.end(j) );
207  const RhsConstIterator rend( B.end(j) );
208 
209  LhsConstIterator lelem( A.begin(j) );
210  RhsConstIterator relem( B.begin(j) );
211 
212  while( lelem != lend && relem != rend )
213  {
214  if( lelem->index() < relem->index() ) {
215  if( !isDefault( lelem->value() ) )
216  return false;
217  ++lelem;
218  }
219  else if( lelem->index() > relem->index() ) {
220  if( !isDefault( relem->value() ) )
221  return false;
222  ++relem;
223  }
224  else if( !equal( lelem->value(), relem->value() ) ) {
225  return false;
226  }
227  else {
228  ++lelem;
229  ++relem;
230  }
231  }
232 
233  while( lelem != lend ) {
234  if( !isDefault( lelem->value() ) )
235  return false;
236  ++lelem;
237  }
238 
239  while( relem != rend ) {
240  if( !isDefault( relem->value() ) )
241  return false;
242  ++relem;
243  }
244  }
245 
246  return true;
247 }
248 //*************************************************************************************************
249 
250 
251 //*************************************************************************************************
259 template< typename T1 // Type of the left-hand side sparse matrix
260  , typename T2 // Type of the right-hand side sparse matrix
261  , bool SO > // Storage order
262 inline bool operator==( const SparseMatrix<T1,SO>& lhs, const SparseMatrix<T2,!SO>& rhs )
263 {
264  const OppositeType_<T2> tmp( ~rhs );
265  return ( ~lhs == tmp );
266 }
267 //*************************************************************************************************
268 
269 
270 //*************************************************************************************************
278 template< typename T1 // Type of the left-hand side sparse matrix
279  , bool SO1 // Storage order of the left-hand side sparse matrix
280  , typename T2 // Type of the right-hand side sparse matrix
281  , bool SO2 > // Storage order of the right-hand side sparse matrix
282 inline bool operator!=( const SparseMatrix<T1,SO1>& lhs, const SparseMatrix<T2,SO2>& rhs )
283 {
284  return !( lhs == rhs );
285 }
286 //*************************************************************************************************
287 
288 
289 
290 
291 //=================================================================================================
292 //
293 // GLOBAL FUNCTIONS
294 //
295 //=================================================================================================
296 
297 //*************************************************************************************************
300 template< typename MT, bool SO >
301 bool isnan( const SparseMatrix<MT,SO>& sm );
302 
303 template< typename MT, bool SO >
304 bool isSymmetric( const SparseMatrix<MT,SO>& sm );
305 
306 template< typename MT, bool SO >
307 bool isHermitian( const SparseMatrix<MT,SO>& sm );
308 
309 template< typename MT, bool SO >
310 bool isUniform( const SparseMatrix<MT,SO>& sm );
311 
312 template< typename MT, bool SO >
313 bool isLower( const SparseMatrix<MT,SO>& sm );
314 
315 template< typename MT, bool SO >
316 bool isUniLower( const SparseMatrix<MT,SO>& sm );
317 
318 template< typename MT, bool SO >
319 bool isStrictlyLower( const SparseMatrix<MT,SO>& sm );
320 
321 template< typename MT, bool SO >
322 bool isUpper( const SparseMatrix<MT,SO>& sm );
323 
324 template< typename MT, bool SO >
325 bool isUniUpper( const SparseMatrix<MT,SO>& sm );
326 
327 template< typename MT, bool SO >
328 bool isStrictlyUpper( const SparseMatrix<MT,SO>& sm );
329 
330 template< typename MT, bool SO >
331 bool isDiagonal( const SparseMatrix<MT,SO>& sm );
332 
333 template< typename MT, bool SO >
334 bool isIdentity( const SparseMatrix<MT,SO>& sm );
335 
336 template< typename MT, bool SO >
337 const ElementType_<MT> min( const SparseMatrix<MT,SO>& sm );
338 
339 template< typename MT, bool SO >
340 const ElementType_<MT> max( const SparseMatrix<MT,SO>& sm );
342 //*************************************************************************************************
343 
344 
345 //*************************************************************************************************
365 template< typename MT // Type of the sparse matrix
366  , bool SO > // Storage order
367 bool isnan( const SparseMatrix<MT,SO>& sm )
368 {
369  typedef CompositeType_<MT> CT;
371 
372  CT A( ~sm ); // Evaluation of the sparse matrix operand
373 
374  if( SO == rowMajor ) {
375  for( size_t i=0UL; i<A.rows(); ++i ) {
376  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
377  if( isnan( element->value() ) ) return true;
378  }
379  }
380  else {
381  for( size_t j=0UL; j<A.columns(); ++j ) {
382  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
383  if( isnan( element->value() ) ) return true;
384  }
385  }
386 
387  return false;
388 }
389 //*************************************************************************************************
390 
391 
392 //*************************************************************************************************
418 template< typename MT // Type of the sparse matrix
419  , bool SO > // Storage order
421 {
422  typedef ResultType_<MT> RT;
423  typedef ReturnType_<MT> RN;
424  typedef CompositeType_<MT> CT;
425  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
427 
429  return true;
430 
431  if( !isSquare( ~sm ) )
432  return false;
433 
434  if( (~sm).rows() < 2UL )
435  return true;
436 
437  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
438 
439  if( SO == rowMajor ) {
440  for( size_t i=0UL; i<A.rows(); ++i ) {
441  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
442  {
443  const size_t j( element->index() );
444 
445  if( i == j || isDefault( element->value() ) )
446  continue;
447 
448  const ConstIterator pos( A.find( j, i ) );
449  if( pos == A.end(j) || !equal( pos->value(), element->value() ) )
450  return false;
451  }
452  }
453  }
454  else {
455  for( size_t j=0UL; j<A.columns(); ++j ) {
456  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
457  {
458  const size_t i( element->index() );
459 
460  if( j == i || isDefault( element->value() ) )
461  continue;
462 
463  const ConstIterator pos( A.find( j, i ) );
464  if( pos == A.end(i) || !equal( pos->value(), element->value() ) )
465  return false;
466  }
467  }
468  }
469 
470  return true;
471 }
472 //*************************************************************************************************
473 
474 
475 //*************************************************************************************************
503 template< typename MT // Type of the sparse matrix
504  , bool SO > // Storage order
506 {
507  typedef ResultType_<MT> RT;
508  typedef ElementType_<MT> ET;
509  typedef ReturnType_<MT> RN;
510  typedef CompositeType_<MT> CT;
511  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
513 
515  return true;
516 
517  if( !IsNumeric<ET>::value || !isSquare( ~sm ) )
518  return false;
519 
520  if( (~sm).rows() < 2UL )
521  return true;
522 
523  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
524 
525  if( SO == rowMajor ) {
526  for( size_t i=0UL; i<A.rows(); ++i ) {
527  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
528  {
529  const size_t j( element->index() );
530 
531  if( isDefault( element->value() ) )
532  continue;
533 
534  if( i == j && !isReal( element->value() ) )
535  return false;
536 
537  const ConstIterator pos( A.find( j, i ) );
538  if( pos == A.end(j) || !equal( pos->value(), conj( element->value() ) ) )
539  return false;
540  }
541  }
542  }
543  else {
544  for( size_t j=0UL; j<A.columns(); ++j ) {
545  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
546  {
547  const size_t i( element->index() );
548 
549  if( isDefault( element->value() ) )
550  continue;
551 
552  if( j == i && !isReal( element->value() ) )
553  return false;
554 
555  const ConstIterator pos( A.find( j, i ) );
556  if( pos == A.end(i) || !equal( pos->value(), conj( element->value() ) ) )
557  return false;
558  }
559  }
560  }
561 
562  return true;
563 }
564 //*************************************************************************************************
565 
566 
567 //*************************************************************************************************
575 template< typename MT > // Type of the sparse matrix
576 bool isUniform_backend( const SparseMatrix<MT,false>& sm, TrueType )
577 {
580 
581  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
582  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
583 
584  typedef ConstIterator_<MT> ConstIterator;
585 
586  const size_t ibegin( ( IsStrictlyLower<MT>::value )?( 1UL ):( 0UL ) );
587  const size_t iend ( ( IsStrictlyUpper<MT>::value )?( (~sm).rows()-1UL ):( (~sm).rows() ) );
588 
589  for( size_t i=ibegin; i<iend; ++i ) {
590  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
591  if( !isDefault( element->value() ) )
592  return false;
593  }
594  }
595 
596  return true;
597 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
610 template< typename MT > // Type of the sparse matrix
611 bool isUniform_backend( const SparseMatrix<MT,true>& sm, TrueType )
612 {
615 
616  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
617  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
618 
619  typedef ConstIterator_<MT> ConstIterator;
620 
621  const size_t jbegin( ( IsStrictlyUpper<MT>::value )?( 1UL ):( 0UL ) );
622  const size_t jend ( ( IsStrictlyLower<MT>::value )?( (~sm).columns()-1UL ):( (~sm).columns() ) );
623 
624  for( size_t j=jbegin; j<jend; ++j ) {
625  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
626  if( !isDefault( element->value() ) )
627  return false;
628  }
629  }
630 
631  return true;
632 }
634 //*************************************************************************************************
635 
636 
637 //*************************************************************************************************
645 template< typename MT > // Type of the sparse matrix
646 bool isUniform_backend( const SparseMatrix<MT,false>& sm, FalseType )
647 {
650 
651  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
652  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
653 
654  typedef ConstReference_<MT> ConstReference;
655  typedef ConstIterator_<MT> ConstIterator;
656 
657  const size_t maxElements( (~sm).rows() * (~sm).columns() );
658 
659  if( (~sm).nonZeros() != maxElements )
660  {
661  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
662  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
663  if( !isDefault( element->value() ) )
664  return false;
665  }
666  }
667  }
668  else
669  {
670  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
671 
672  ConstReference cmp( (~sm)(0UL,0UL) );
673 
674  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
675  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
676  if( element->value() != cmp )
677  return false;
678  }
679  }
680  }
681 
682  return true;
683 }
685 //*************************************************************************************************
686 
687 
688 //*************************************************************************************************
696 template< typename MT > // Type of the sparse matrix
697 bool isUniform_backend( const SparseMatrix<MT,true>& sm, FalseType )
698 {
701 
702  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
703  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
704 
705  typedef ConstReference_<MT> ConstReference;
706  typedef ConstIterator_<MT> ConstIterator;
707 
708  const size_t maxElements( (~sm).rows() * (~sm).columns() );
709 
710  if( (~sm).nonZeros() != maxElements )
711  {
712  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
713  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
714  if( !isDefault( element->value() ) )
715  return false;
716  }
717  }
718  }
719  else
720  {
721  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
722 
723  ConstReference cmp( (~sm)(0UL,0UL) );
724 
725  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
726  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
727  if( element->value() != cmp )
728  return false;
729  }
730  }
731  }
732 
733  return true;
734 }
736 //*************************************************************************************************
737 
738 
739 //*************************************************************************************************
765 template< typename MT // Type of the sparse matrix
766  , bool SO > // Storage order
768 {
770  return false;
771 
772  if( (~sm).rows() == 0UL || (~sm).columns() == 0UL ||
773  ( (~sm).rows() == 1UL && (~sm).columns() == 1UL ) )
774  return true;
775 
776  CompositeType_<MT> A( ~sm ); // Evaluation of the sparse matrix operand
777 
778  return isUniform_backend( A, typename IsTriangular<MT>::Type() );
779 }
780 //*************************************************************************************************
781 
782 
783 //*************************************************************************************************
819 template< typename MT // Type of the sparse matrix
820  , bool SO > // Storage order
821 bool isLower( const SparseMatrix<MT,SO>& sm )
822 {
823  typedef ResultType_<MT> RT;
824  typedef ReturnType_<MT> RN;
825  typedef CompositeType_<MT> CT;
826  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
828 
829  if( IsLower<MT>::value )
830  return true;
831 
832  if( !isSquare( ~sm ) )
833  return false;
834 
835  if( (~sm).rows() < 2UL )
836  return true;
837 
838  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
839 
840  if( SO == rowMajor ) {
841  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
842  for( ConstIterator element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
843  {
844  if( !isDefault( element->value() ) )
845  return false;
846  }
847  }
848  }
849  else {
850  for( size_t j=1UL; j<A.columns(); ++j ) {
851  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
852  {
853  if( element->index() >= j )
854  break;
855 
856  if( !isDefault( element->value() ) )
857  return false;
858  }
859  }
860  }
861 
862  return true;
863 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
902 template< typename MT // Type of the sparse matrix
903  , bool SO > // Storage order
905 {
906  typedef ResultType_<MT> RT;
907  typedef ReturnType_<MT> RN;
908  typedef CompositeType_<MT> CT;
909  typedef If_< IsExpression<RN>, const RT, CT > 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( !isZero( 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( !isZero( 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 ResultType_<MT> RT;
1006  typedef ReturnType_<MT> RN;
1007  typedef CompositeType_<MT> CT;
1008  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1010 
1012  return true;
1013 
1015  return false;
1016 
1017  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1018 
1019  if( SO == rowMajor ) {
1020  for( size_t i=0UL; i<A.rows(); ++i ) {
1021  for( ConstIterator element=A.lowerBound(i,i); element!=A.end(i); ++element )
1022  {
1023  if( !isDefault( element->value() ) )
1024  return false;
1025  }
1026  }
1027  }
1028  else {
1029  for( size_t j=0UL; j<A.columns(); ++j ) {
1030  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1031  {
1032  if( element->index() > j )
1033  break;
1034 
1035  if( !isDefault( element->value() ) )
1036  return false;
1037  }
1038  }
1039  }
1040 
1041  return true;
1042 }
1043 //*************************************************************************************************
1044 
1045 
1046 //*************************************************************************************************
1082 template< typename MT // Type of the sparse matrix
1083  , bool SO > // Storage order
1084 bool isUpper( const SparseMatrix<MT,SO>& sm )
1085 {
1086  typedef ResultType_<MT> RT;
1087  typedef ReturnType_<MT> RN;
1088  typedef CompositeType_<MT> CT;
1089  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1091 
1092  if( IsUpper<MT>::value )
1093  return true;
1094 
1095  if( !isSquare( ~sm ) )
1096  return false;
1097 
1098  if( (~sm).rows() < 2UL )
1099  return true;
1100 
1101  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1102 
1103  if( SO == rowMajor ) {
1104  for( size_t i=1UL; i<A.rows(); ++i ) {
1105  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1106  {
1107  if( element->index() >= i )
1108  break;
1109 
1110  if( !isDefault( element->value() ) )
1111  return false;
1112  }
1113  }
1114  }
1115  else {
1116  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
1117  for( ConstIterator element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
1118  {
1119  if( !isDefault( element->value() ) )
1120  return false;
1121  }
1122  }
1123  }
1124 
1125  return true;
1126 }
1127 //*************************************************************************************************
1128 
1129 
1130 //*************************************************************************************************
1165 template< typename MT // Type of the sparse matrix
1166  , bool SO > // Storage order
1168 {
1169  typedef ResultType_<MT> RT;
1170  typedef ReturnType_<MT> RN;
1171  typedef CompositeType_<MT> CT;
1172  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1174 
1175  if( IsUniUpper<MT>::value )
1176  return true;
1177 
1178  if( !isSquare( ~sm ) )
1179  return false;
1180 
1181  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1182 
1183  if( SO == rowMajor ) {
1184  for( size_t i=0UL; i<A.rows(); ++i )
1185  {
1186  bool hasDiagonalElement( false );
1187 
1188  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1189  {
1190  if( element->index() >= i ) {
1191  if( element->index() != i || !isOne( element->value() ) )
1192  return false;
1193  hasDiagonalElement = true;
1194  break;
1195  }
1196  else if( !isZero( element->value() ) ) {
1197  return false;
1198  }
1199  }
1200 
1201  if( !hasDiagonalElement ) {
1202  return false;
1203  }
1204  }
1205  }
1206  else {
1207  for( size_t j=0UL; j<A.columns(); ++j )
1208  {
1209  ConstIterator element( A.lowerBound(j,j) );
1210 
1211  if( element == A.end(j) || element->index() != j || !isOne( element->value() ) )
1212  return false;
1213 
1214  ++element;
1215 
1216  for( ; element!=A.end(j); ++element ) {
1217  if( !isZero( element->value() ) )
1218  return false;
1219  }
1220  }
1221  }
1222 
1223  return true;
1224 }
1225 //*************************************************************************************************
1226 
1227 
1228 //*************************************************************************************************
1264 template< typename MT // Type of the sparse matrix
1265  , bool SO > // Storage order
1267 {
1268  typedef ResultType_<MT> RT;
1269  typedef ReturnType_<MT> RN;
1270  typedef CompositeType_<MT> CT;
1271  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1273 
1275  return true;
1276 
1278  return false;
1279 
1280  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1281 
1282  if( SO == rowMajor ) {
1283  for( size_t i=0UL; i<A.rows(); ++i ) {
1284  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1285  {
1286  if( element->index() > i )
1287  break;
1288 
1289  if( !isDefault( element->value() ) )
1290  return false;
1291  }
1292  }
1293  }
1294  else {
1295  for( size_t j=0UL; j<A.columns(); ++j ) {
1296  for( ConstIterator element=A.lowerBound(j,j); element!=A.end(j); ++element )
1297  {
1298  if( !isDefault( element->value() ) )
1299  return false;
1300  }
1301  }
1302  }
1303 
1304  return true;
1305 }
1306 //*************************************************************************************************
1307 
1308 
1309 //*************************************************************************************************
1345 template< typename MT // Type of the sparse matrix
1346  , bool SO > // Storage order
1348 {
1349  typedef ResultType_<MT> RT;
1350  typedef ReturnType_<MT> RN;
1351  typedef CompositeType_<MT> CT;
1352  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1354 
1355  if( IsDiagonal<MT>::value )
1356  return true;
1357 
1358  if( !isSquare( ~sm ) )
1359  return false;
1360 
1361  if( (~sm).rows() < 2UL )
1362  return true;
1363 
1364  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1365 
1366  if( SO == rowMajor ) {
1367  for( size_t i=0UL; i<A.rows(); ++i ) {
1368  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1369  if( element->index() != i && !isDefault( element->value() ) )
1370  return false;
1371  }
1372  }
1373  else {
1374  for( size_t j=0UL; j<A.columns(); ++j ) {
1375  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1376  if( element->index() != j && !isDefault( element->value() ) )
1377  return false;
1378  }
1379  }
1380 
1381  return true;
1382 }
1383 //*************************************************************************************************
1384 
1385 
1386 //*************************************************************************************************
1422 template< typename MT // Type of the sparse matrix
1423  , bool SO > // Storage order
1425 {
1426  typedef ResultType_<MT> RT;
1427  typedef ReturnType_<MT> RN;
1428  typedef CompositeType_<MT> CT;
1429  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1431 
1432  if( IsIdentity<MT>::value )
1433  return true;
1434 
1435  if( !isSquare( ~sm ) )
1436  return false;
1437 
1438  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1439 
1440  if( SO == rowMajor ) {
1441  for( size_t i=0UL; i<A.rows(); ++i )
1442  {
1443  bool hasDiagonalElement( false );
1444 
1445  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1446  {
1447  if( element->index() == i ) {
1448  if( !isOne( element->value() ) )
1449  return false;
1450  hasDiagonalElement = true;
1451  }
1452  else if( !isZero( element->value() ) ) {
1453  return false;
1454  }
1455  }
1456 
1457  if( !hasDiagonalElement ) {
1458  return false;
1459  }
1460  }
1461  }
1462  else {
1463  for( size_t j=0UL; j<A.columns(); ++j )
1464  {
1465  bool hasDiagonalElement( false );
1466 
1467  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1468  {
1469  if( element->index() == j ) {
1470  if( !isOne( element->value() ) )
1471  return false;
1472  hasDiagonalElement = true;
1473  }
1474  else if( !isZero( element->value() ) ) {
1475  return false;
1476  }
1477  }
1478 
1479  if( !hasDiagonalElement ) {
1480  return false;
1481  }
1482  }
1483  }
1484 
1485  return true;
1486 }
1487 //*************************************************************************************************
1488 
1489 
1490 //*************************************************************************************************
1502 template< typename MT // Type of the sparse matrix
1503  , bool SO > // Storage order
1505 {
1506  using blaze::min;
1507 
1508  typedef ElementType_<MT> ET;
1509  typedef CompositeType_<MT> CT;
1511 
1512  CT A( ~sm ); // Evaluation of the sparse matrix operand
1513 
1514  const size_t nonzeros( A.nonZeros() );
1515 
1516  if( nonzeros == 0UL ) {
1517  return ET();
1518  }
1519 
1520  ET minimum = ET();
1521  if( nonzeros == A.rows() * A.columns() ) {
1522  minimum = A.begin( 0UL )->value();
1523  }
1524 
1525  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1526 
1527  for( size_t i=0UL; i<index; ++i ) {
1528  const ConstIterator end( A.end( i ) );
1529  ConstIterator element( A.begin( i ) );
1530  for( ; element!=end; ++element )
1531  minimum = min( minimum, element->value() );
1532  }
1533 
1534  return minimum;
1535 }
1536 //*************************************************************************************************
1537 
1538 
1539 //*************************************************************************************************
1551 template< typename MT // Type of the sparse matrix
1552  , bool SO > // Storage order
1554 {
1555  using blaze::max;
1556 
1557  typedef ElementType_<MT> ET;
1558  typedef CompositeType_<MT> CT;
1560 
1561  CT A( ~sm ); // Evaluation of the sparse matrix operand
1562 
1563  const size_t nonzeros( A.nonZeros() );
1564 
1565  if( nonzeros == 0UL ) {
1566  return ET();
1567  }
1568 
1569  ET maximum = ET();
1570  if( nonzeros == A.rows() * A.columns() ) {
1571  maximum = A.begin( 0UL )->value();
1572  }
1573 
1574  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1575 
1576  for( size_t i=0UL; i<index; ++i ) {
1577  const ConstIterator end( A.end( i ) );
1578  ConstIterator element( A.begin( i ) );
1579  for( ; element!=end; ++element )
1580  maximum = max( maximum, element->value() );
1581  }
1582 
1583  return maximum;
1584 }
1585 //*************************************************************************************************
1586 
1587 } // namespace blaze
1588 
1589 #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:61
Header file for the isnan shim.
BoolConstant< false > 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 isOne(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 1.
Definition: DiagonalProxy.h:635
const DMatForEachExpr< MT, Conj, SO > conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatForEachExpr.h:1158
Header file for auxiliary alias declarations.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
Header file for mathematical functions.
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1499
Header file for the IsUniUpper type trait.
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:87
Header file for basic type definitions.
#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:81
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1192
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1423
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:595
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:689
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:188
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
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:384
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
BoolConstant< true > 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 IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1036
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:343
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.
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
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:2647
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
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:90
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
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:1267
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:655
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:1113
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:254
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
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:86
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:90
Header file for run time assertion macros.
bool equal(const T1 &a, const T2 &b)
Generic equality check.
Definition: Equal.h:73
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:160
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:81
Header file for the RemoveReference type trait.
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:243
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
bool isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:982
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:759
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:615
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
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:1344
Header file for the IsUpper type trait.
Header file for the IsHermitian type trait.
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:609
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:87
bool isIdentity(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is an identity matrix.
Definition: DenseMatrix.h:1593
Header file for the IsExpression type trait class.