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< bool RF, typename MT, bool SO >
304 bool isSymmetric( const SparseMatrix<MT,SO>& sm );
305 
306 template< bool RF, typename MT, bool SO >
307 bool isHermitian( const SparseMatrix<MT,SO>& sm );
308 
309 template< bool RF, typename MT, bool SO >
310 bool isUniform( const SparseMatrix<MT,SO>& sm );
311 
312 template< bool RF, typename MT, bool SO >
313 bool isLower( const SparseMatrix<MT,SO>& sm );
314 
315 template< bool RF, typename MT, bool SO >
316 bool isUniLower( const SparseMatrix<MT,SO>& sm );
317 
318 template< bool RF, typename MT, bool SO >
319 bool isStrictlyLower( const SparseMatrix<MT,SO>& sm );
320 
321 template< bool RF, typename MT, bool SO >
322 bool isUpper( const SparseMatrix<MT,SO>& sm );
323 
324 template< bool RF, typename MT, bool SO >
325 bool isUniUpper( const SparseMatrix<MT,SO>& sm );
326 
327 template< bool RF, typename MT, bool SO >
328 bool isStrictlyUpper( const SparseMatrix<MT,SO>& sm );
329 
330 template< bool RF, typename MT, bool SO >
331 bool isDiagonal( const SparseMatrix<MT,SO>& sm );
332 
333 template< bool RF, 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 //*************************************************************************************************
425 template< bool RF // Relaxation flag
426  , typename MT // Type of the sparse matrix
427  , bool SO > // Storage order
429 {
430  typedef ResultType_<MT> RT;
431  typedef ReturnType_<MT> RN;
432  typedef CompositeType_<MT> CT;
433  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
435 
437  return true;
438 
439  if( !isSquare( ~sm ) )
440  return false;
441 
442  if( (~sm).rows() < 2UL )
443  return true;
444 
445  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
446 
447  if( SO == rowMajor ) {
448  for( size_t i=0UL; i<A.rows(); ++i ) {
449  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
450  {
451  const size_t j( element->index() );
452 
453  if( i == j || isDefault<RF>( element->value() ) )
454  continue;
455 
456  const ConstIterator pos( A.find( j, i ) );
457  if( pos == A.end(j) || !equal<RF>( pos->value(), element->value() ) )
458  return false;
459  }
460  }
461  }
462  else {
463  for( size_t j=0UL; j<A.columns(); ++j ) {
464  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
465  {
466  const size_t i( element->index() );
467 
468  if( j == i || isDefault<RF>( element->value() ) )
469  continue;
470 
471  const ConstIterator pos( A.find( j, i ) );
472  if( pos == A.end(i) || !equal<RF>( pos->value(), element->value() ) )
473  return false;
474  }
475  }
476  }
477 
478  return true;
479 }
480 //*************************************************************************************************
481 
482 
483 //*************************************************************************************************
518 template< bool RF // Relaxation flag
519  , typename MT // Type of the sparse matrix
520  , bool SO > // Storage order
522 {
523  typedef ResultType_<MT> RT;
524  typedef ElementType_<MT> ET;
525  typedef ReturnType_<MT> RN;
526  typedef CompositeType_<MT> CT;
527  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
529 
531  return true;
532 
533  if( !IsNumeric<ET>::value || !isSquare( ~sm ) )
534  return false;
535 
536  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
537 
538  if( SO == rowMajor ) {
539  for( size_t i=0UL; i<A.rows(); ++i ) {
540  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
541  {
542  const size_t j( element->index() );
543 
544  if( isDefault<RF>( element->value() ) )
545  continue;
546 
547  if( i == j && !isReal<RF>( element->value() ) )
548  return false;
549 
550  const ConstIterator pos( A.find( j, i ) );
551  if( pos == A.end(j) || !equal<RF>( pos->value(), conj( element->value() ) ) )
552  return false;
553  }
554  }
555  }
556  else {
557  for( size_t j=0UL; j<A.columns(); ++j ) {
558  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
559  {
560  const size_t i( element->index() );
561 
562  if( isDefault<RF>( element->value() ) )
563  continue;
564 
565  if( j == i && !isReal<RF>( element->value() ) )
566  return false;
567 
568  const ConstIterator pos( A.find( j, i ) );
569  if( pos == A.end(i) || !equal<RF>( pos->value(), conj( element->value() ) ) )
570  return false;
571  }
572  }
573  }
574 
575  return true;
576 }
577 //*************************************************************************************************
578 
579 
580 //*************************************************************************************************
588 template< bool RF // Relaxation flag
589  , typename MT > // Type of the sparse matrix
590 bool isUniform_backend( const SparseMatrix<MT,false>& sm, TrueType )
591 {
594 
595  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
596  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
597 
599 
600  const size_t ibegin( ( IsStrictlyLower<MT>::value )?( 1UL ):( 0UL ) );
601  const size_t iend ( ( IsStrictlyUpper<MT>::value )?( (~sm).rows()-1UL ):( (~sm).rows() ) );
602 
603  for( size_t i=ibegin; i<iend; ++i ) {
604  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
605  if( !isDefault<RF>( element->value() ) )
606  return false;
607  }
608  }
609 
610  return true;
611 }
613 //*************************************************************************************************
614 
615 
616 //*************************************************************************************************
624 template< bool RF // Relaxation flag
625  , typename MT > // Type of the sparse matrix
626 bool isUniform_backend( const SparseMatrix<MT,true>& sm, TrueType )
627 {
630 
631  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
632  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
633 
635 
636  const size_t jbegin( ( IsStrictlyUpper<MT>::value )?( 1UL ):( 0UL ) );
637  const size_t jend ( ( IsStrictlyLower<MT>::value )?( (~sm).columns()-1UL ):( (~sm).columns() ) );
638 
639  for( size_t j=jbegin; j<jend; ++j ) {
640  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
641  if( !isDefault<RF>( element->value() ) )
642  return false;
643  }
644  }
645 
646  return true;
647 }
649 //*************************************************************************************************
650 
651 
652 //*************************************************************************************************
660 template< bool RF // Relaxation flag
661  , typename MT > // Type of the sparse matrix
662 bool isUniform_backend( const SparseMatrix<MT,false>& sm, FalseType )
663 {
666 
667  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
668  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
669 
672 
673  const size_t maxElements( (~sm).rows() * (~sm).columns() );
674 
675  if( (~sm).nonZeros() != maxElements )
676  {
677  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
678  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
679  if( !isDefault<RF>( element->value() ) )
680  return false;
681  }
682  }
683  }
684  else
685  {
686  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
687 
688  ConstReference cmp( (~sm)(0UL,0UL) );
689 
690  for( size_t i=0UL; i<(~sm).rows(); ++i ) {
691  for( ConstIterator element=(~sm).begin(i); element!=(~sm).end(i); ++element ) {
692  if( element->value() != cmp )
693  return false;
694  }
695  }
696  }
697 
698  return true;
699 }
701 //*************************************************************************************************
702 
703 
704 //*************************************************************************************************
712 template< bool RF // Relaxation flag
713  , typename MT > // Type of the sparse matrix
714 bool isUniform_backend( const SparseMatrix<MT,true>& sm, FalseType )
715 {
718 
719  BLAZE_INTERNAL_ASSERT( (~sm).rows() != 0UL, "Invalid number of rows detected" );
720  BLAZE_INTERNAL_ASSERT( (~sm).columns() != 0UL, "Invalid number of columns detected" );
721 
724 
725  const size_t maxElements( (~sm).rows() * (~sm).columns() );
726 
727  if( (~sm).nonZeros() != maxElements )
728  {
729  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
730  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
731  if( !isDefault<RF>( element->value() ) )
732  return false;
733  }
734  }
735  }
736  else
737  {
738  BLAZE_INTERNAL_ASSERT( (~sm).find(0UL,0UL) != (~sm).end(0UL), "Missing element detected" );
739 
740  ConstReference cmp( (~sm)(0UL,0UL) );
741 
742  for( size_t j=0UL; j<(~sm).columns(); ++j ) {
743  for( ConstIterator element=(~sm).begin(j); element!=(~sm).end(j); ++element ) {
744  if( element->value() != cmp )
745  return false;
746  }
747  }
748  }
749 
750  return true;
751 }
753 //*************************************************************************************************
754 
755 
756 //*************************************************************************************************
789 template< bool RF // Relaxation flag
790  , typename MT // Type of the sparse matrix
791  , bool SO > // Storage order
793 {
795  return false;
796 
797  if( (~sm).rows() == 0UL || (~sm).columns() == 0UL ||
798  ( (~sm).rows() == 1UL && (~sm).columns() == 1UL ) )
799  return true;
800 
801  CompositeType_<MT> A( ~sm ); // Evaluation of the sparse matrix operand
802 
803  return isUniform_backend<RF>( A, typename IsTriangular<MT>::Type() );
804 }
805 //*************************************************************************************************
806 
807 
808 //*************************************************************************************************
851 template< bool RF // Relaxation flag
852  , typename MT // Type of the sparse matrix
853  , bool SO > // Storage order
854 bool isLower( const SparseMatrix<MT,SO>& sm )
855 {
856  typedef ResultType_<MT> RT;
857  typedef ReturnType_<MT> RN;
858  typedef CompositeType_<MT> CT;
859  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
861 
862  if( IsLower<MT>::value )
863  return true;
864 
865  if( !isSquare( ~sm ) )
866  return false;
867 
868  if( (~sm).rows() < 2UL )
869  return true;
870 
871  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
872 
873  if( SO == rowMajor ) {
874  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
875  for( ConstIterator element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
876  {
877  if( !isDefault<RF>( element->value() ) )
878  return false;
879  }
880  }
881  }
882  else {
883  for( size_t j=1UL; j<A.columns(); ++j ) {
884  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
885  {
886  if( element->index() >= j )
887  break;
888 
889  if( !isDefault<RF>( element->value() ) )
890  return false;
891  }
892  }
893  }
894 
895  return true;
896 }
897 //*************************************************************************************************
898 
899 
900 //*************************************************************************************************
942 template< bool RF // Relaxation flag
943  , typename MT // Type of the sparse matrix
944  , bool SO > // Storage order
946 {
947  typedef ResultType_<MT> RT;
948  typedef ReturnType_<MT> RN;
949  typedef CompositeType_<MT> CT;
950  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
952 
954  return true;
955 
956  if( !isSquare( ~sm ) )
957  return false;
958 
959  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
960 
961  if( SO == rowMajor ) {
962  for( size_t i=0UL; i<A.rows(); ++i )
963  {
964  ConstIterator element( A.lowerBound(i,i) );
965 
966  if( element == A.end(i) || element->index() != i || !isOne<RF>( element->value() ) )
967  return false;
968 
969  ++element;
970 
971  for( ; element!=A.end(i); ++element ) {
972  if( !isZero<RF>( element->value() ) )
973  return false;
974  }
975  }
976  }
977  else {
978  for( size_t j=0UL; j<A.columns(); ++j )
979  {
980  bool hasDiagonalElement( false );
981 
982  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
983  {
984  if( element->index() >= j ) {
985  if( element->index() != j || !isOne<RF>( element->value() ) )
986  return false;
987  hasDiagonalElement = true;
988  break;
989  }
990 
991  if( !isZero<RF>( element->value() ) )
992  return false;
993  }
994 
995  if( !hasDiagonalElement ) {
996  return false;
997  }
998  }
999  }
1000 
1001  return true;
1002 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1049 template< bool RF // Relaxation flag
1050  , typename MT // Type of the sparse matrix
1051  , bool SO > // Storage order
1053 {
1054  typedef ResultType_<MT> RT;
1055  typedef ReturnType_<MT> RN;
1056  typedef CompositeType_<MT> CT;
1057  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1059 
1061  return true;
1062 
1064  return false;
1065 
1066  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1067 
1068  if( SO == rowMajor ) {
1069  for( size_t i=0UL; i<A.rows(); ++i ) {
1070  for( ConstIterator element=A.lowerBound(i,i); element!=A.end(i); ++element )
1071  {
1072  if( !isDefault<RF>( element->value() ) )
1073  return false;
1074  }
1075  }
1076  }
1077  else {
1078  for( size_t j=0UL; j<A.columns(); ++j ) {
1079  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1080  {
1081  if( element->index() > j )
1082  break;
1083 
1084  if( !isDefault<RF>( element->value() ) )
1085  return false;
1086  }
1087  }
1088  }
1089 
1090  return true;
1091 }
1092 //*************************************************************************************************
1093 
1094 
1095 //*************************************************************************************************
1138 template< bool RF // Relaxation flag
1139  , typename MT // Type of the sparse matrix
1140  , bool SO > // Storage order
1141 bool isUpper( const SparseMatrix<MT,SO>& sm )
1142 {
1143  typedef ResultType_<MT> RT;
1144  typedef ReturnType_<MT> RN;
1145  typedef CompositeType_<MT> CT;
1146  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1148 
1149  if( IsUpper<MT>::value )
1150  return true;
1151 
1152  if( !isSquare( ~sm ) )
1153  return false;
1154 
1155  if( (~sm).rows() < 2UL )
1156  return true;
1157 
1158  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1159 
1160  if( SO == rowMajor ) {
1161  for( size_t i=1UL; i<A.rows(); ++i ) {
1162  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1163  {
1164  if( element->index() >= i )
1165  break;
1166 
1167  if( !isDefault<RF>( element->value() ) )
1168  return false;
1169  }
1170  }
1171  }
1172  else {
1173  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
1174  for( ConstIterator element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
1175  {
1176  if( !isDefault<RF>( element->value() ) )
1177  return false;
1178  }
1179  }
1180  }
1181 
1182  return true;
1183 }
1184 //*************************************************************************************************
1185 
1186 
1187 //*************************************************************************************************
1229 template< bool RF // Relaxation flag
1230  , typename MT // Type of the sparse matrix
1231  , bool SO > // Storage order
1233 {
1234  typedef ResultType_<MT> RT;
1235  typedef ReturnType_<MT> RN;
1236  typedef CompositeType_<MT> CT;
1237  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1239 
1240  if( IsUniUpper<MT>::value )
1241  return true;
1242 
1243  if( !isSquare( ~sm ) )
1244  return false;
1245 
1246  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1247 
1248  if( SO == rowMajor ) {
1249  for( size_t i=0UL; i<A.rows(); ++i )
1250  {
1251  bool hasDiagonalElement( false );
1252 
1253  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1254  {
1255  if( element->index() >= i ) {
1256  if( element->index() != i || !isOne<RF>( element->value() ) )
1257  return false;
1258  hasDiagonalElement = true;
1259  break;
1260  }
1261  else if( !isZero<RF>( element->value() ) ) {
1262  return false;
1263  }
1264  }
1265 
1266  if( !hasDiagonalElement ) {
1267  return false;
1268  }
1269  }
1270  }
1271  else {
1272  for( size_t j=0UL; j<A.columns(); ++j )
1273  {
1274  ConstIterator element( A.lowerBound(j,j) );
1275 
1276  if( element == A.end(j) || element->index() != j || !isOne<RF>( element->value() ) )
1277  return false;
1278 
1279  ++element;
1280 
1281  for( ; element!=A.end(j); ++element ) {
1282  if( !isZero<RF>( element->value() ) )
1283  return false;
1284  }
1285  }
1286  }
1287 
1288  return true;
1289 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1336 template< bool RF // Relaxation flag
1337  , typename MT // Type of the sparse matrix
1338  , bool SO > // Storage order
1340 {
1341  typedef ResultType_<MT> RT;
1342  typedef ReturnType_<MT> RN;
1343  typedef CompositeType_<MT> CT;
1344  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1346 
1348  return true;
1349 
1351  return false;
1352 
1353  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1354 
1355  if( SO == rowMajor ) {
1356  for( size_t i=0UL; i<A.rows(); ++i ) {
1357  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1358  {
1359  if( element->index() > i )
1360  break;
1361 
1362  if( !isDefault<RF>( element->value() ) )
1363  return false;
1364  }
1365  }
1366  }
1367  else {
1368  for( size_t j=0UL; j<A.columns(); ++j ) {
1369  for( ConstIterator element=A.lowerBound(j,j); element!=A.end(j); ++element )
1370  {
1371  if( !isDefault<RF>( element->value() ) )
1372  return false;
1373  }
1374  }
1375  }
1376 
1377  return true;
1378 }
1379 //*************************************************************************************************
1380 
1381 
1382 //*************************************************************************************************
1425 template< bool RF // Relaxation flag
1426  , typename MT // Type of the sparse matrix
1427  , bool SO > // Storage order
1429 {
1430  typedef ResultType_<MT> RT;
1431  typedef ReturnType_<MT> RN;
1432  typedef CompositeType_<MT> CT;
1433  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1435 
1436  if( IsDiagonal<MT>::value )
1437  return true;
1438 
1439  if( !isSquare( ~sm ) )
1440  return false;
1441 
1442  if( (~sm).rows() < 2UL )
1443  return true;
1444 
1445  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1446 
1447  if( SO == rowMajor ) {
1448  for( size_t i=0UL; i<A.rows(); ++i ) {
1449  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1450  if( element->index() != i && !isDefault<RF>( element->value() ) )
1451  return false;
1452  }
1453  }
1454  else {
1455  for( size_t j=0UL; j<A.columns(); ++j ) {
1456  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1457  if( element->index() != j && !isDefault<RF>( element->value() ) )
1458  return false;
1459  }
1460  }
1461 
1462  return true;
1463 }
1464 //*************************************************************************************************
1465 
1466 
1467 //*************************************************************************************************
1510 template< bool RF // Relaxation flag
1511  , typename MT // Type of the sparse matrix
1512  , bool SO > // Storage order
1514 {
1515  typedef ResultType_<MT> RT;
1516  typedef ReturnType_<MT> RN;
1517  typedef CompositeType_<MT> CT;
1518  typedef If_< IsExpression<RN>, const RT, CT > Tmp;
1520 
1521  if( IsIdentity<MT>::value )
1522  return true;
1523 
1524  if( !isSquare( ~sm ) )
1525  return false;
1526 
1527  Tmp A( ~sm ); // Evaluation of the sparse matrix operand
1528 
1529  if( SO == rowMajor ) {
1530  for( size_t i=0UL; i<A.rows(); ++i )
1531  {
1532  bool hasDiagonalElement( false );
1533 
1534  for( ConstIterator element=A.begin(i); element!=A.end(i); ++element )
1535  {
1536  if( element->index() == i ) {
1537  if( !isOne<RF>( element->value() ) )
1538  return false;
1539  hasDiagonalElement = true;
1540  }
1541  else if( !isZero<RF>( element->value() ) ) {
1542  return false;
1543  }
1544  }
1545 
1546  if( !hasDiagonalElement ) {
1547  return false;
1548  }
1549  }
1550  }
1551  else {
1552  for( size_t j=0UL; j<A.columns(); ++j )
1553  {
1554  bool hasDiagonalElement( false );
1555 
1556  for( ConstIterator element=A.begin(j); element!=A.end(j); ++element )
1557  {
1558  if( element->index() == j ) {
1559  if( !isOne<RF>( element->value() ) )
1560  return false;
1561  hasDiagonalElement = true;
1562  }
1563  else if( !isZero<RF>( element->value() ) ) {
1564  return false;
1565  }
1566  }
1567 
1568  if( !hasDiagonalElement ) {
1569  return false;
1570  }
1571  }
1572  }
1573 
1574  return true;
1575 }
1576 //*************************************************************************************************
1577 
1578 
1579 //*************************************************************************************************
1591 template< typename MT // Type of the sparse matrix
1592  , bool SO > // Storage order
1594 {
1595  using blaze::min;
1596 
1597  typedef ElementType_<MT> ET;
1598  typedef CompositeType_<MT> CT;
1600 
1601  CT A( ~sm ); // Evaluation of the sparse matrix operand
1602 
1603  const size_t nonzeros( A.nonZeros() );
1604 
1605  if( nonzeros == 0UL ) {
1606  return ET();
1607  }
1608 
1609  ET minimum = ET();
1610  if( nonzeros == A.rows() * A.columns() ) {
1611  minimum = A.begin( 0UL )->value();
1612  }
1613 
1614  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1615 
1616  for( size_t i=0UL; i<index; ++i ) {
1617  const ConstIterator end( A.end( i ) );
1618  ConstIterator element( A.begin( i ) );
1619  for( ; element!=end; ++element )
1620  minimum = min( minimum, element->value() );
1621  }
1622 
1623  return minimum;
1624 }
1625 //*************************************************************************************************
1626 
1627 
1628 //*************************************************************************************************
1640 template< typename MT // Type of the sparse matrix
1641  , bool SO > // Storage order
1643 {
1644  using blaze::max;
1645 
1646  typedef ElementType_<MT> ET;
1647  typedef CompositeType_<MT> CT;
1649 
1650  CT A( ~sm ); // Evaluation of the sparse matrix operand
1651 
1652  const size_t nonzeros( A.nonZeros() );
1653 
1654  if( nonzeros == 0UL ) {
1655  return ET();
1656  }
1657 
1658  ET maximum = ET();
1659  if( nonzeros == A.rows() * A.columns() ) {
1660  maximum = A.begin( 0UL )->value();
1661  }
1662 
1663  const size_t index( ( SO == rowMajor )?( A.rows() ):( A.columns() ) );
1664 
1665  for( size_t i=0UL; i<index; ++i ) {
1666  const ConstIterator end( A.end( i ) );
1667  ConstIterator element( A.begin( i ) );
1668  for( ; element!=end; ++element )
1669  maximum = max( maximum, element->value() );
1670  }
1671 
1672  return maximum;
1673 }
1674 //*************************************************************************************************
1675 
1676 } // namespace blaze
1677 
1678 #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.
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:1214
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 isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1066
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1321
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1238
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
constexpr bool equal(const T1 &a, const T2 &b)
Generic equality check.
Definition: Equal.h:76
Header file for the FalseType type/value trait base class.
Header file for the IsDiagonal type trait.
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
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:194
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1151
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1755
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.
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1577
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:390
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
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:1802
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
bool isIdentity(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is an identity matrix.
Definition: DenseMatrix.h:1679
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:2939
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
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:336
Header file for the equal shim.
Header file for the IsUniTriangular type trait.
Header file for the IsTriangular type trait.
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 isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:1004
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:260
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2937
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
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1493
Header file for run time assertion macros.
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
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:775
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
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:697
#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
typename T::ConstReference ConstReference_
Alias declaration for nested ConstReference type definitions.The ConstReference_ alias declaration pr...
Definition: Aliases.h:143
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:320
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:1406
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
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:677
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
Header file for the IsExpression type trait class.