Blaze 3.9
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 <utility>
44#include <blaze/math/Aliases.h>
83#include <blaze/util/Assert.h>
84#include <blaze/util/EnableIf.h>
86#include <blaze/util/mpl/If.h>
87#include <blaze/util/Types.h>
91
92
93namespace blaze {
94
95//=================================================================================================
96//
97// GLOBAL OPERATORS
98//
99//=================================================================================================
100
101//*************************************************************************************************
104template< typename MT, bool SO, typename ST >
105auto operator*=( SparseMatrix<MT,SO>& mat, ST scalar )
106 -> EnableIf_t< IsScalar_v<ST>, MT& >;
107
108template< typename MT, bool SO, typename ST >
109auto operator*=( SparseMatrix<MT,SO>&& mat, ST scalar )
110 -> EnableIf_t< IsScalar_v<ST>, MT& >;
111
112template< typename MT, bool SO, typename ST >
113auto operator/=( SparseMatrix<MT,SO>& mat, ST scalar )
114 -> EnableIf_t< IsScalar_v<ST>, MT& >;
115
116template< typename MT, bool SO, typename ST >
117auto operator/=( SparseMatrix<MT,SO>&& mat, ST scalar )
118 -> EnableIf_t< IsScalar_v<ST>, MT& >;
120//*************************************************************************************************
121
122
123//*************************************************************************************************
136template< typename MT // Type of the left-hand side sparse matrix
137 , bool SO // Storage order
138 , typename ST > // Data type of the right-hand side scalar
139inline auto operator*=( SparseMatrix<MT,SO>& mat, ST scalar )
141{
143
144 if( IsRestricted_v<MT> ) {
145 if( !tryMult( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
146 BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
147 }
148 }
149
150 if( !IsResizable_v< ElementType_t<MT> > && isZero( scalar ) )
151 {
152 reset( *mat );
153 }
154 else
155 {
156 decltype(auto) left( derestrict( *mat ) );
157
158 const size_t iend( SO == rowMajor ? (*mat).rows() : (*mat).columns() );
159 for( size_t i=0UL; i<iend; ++i ) {
160 const auto last( left.end(i) );
161 for( auto element=left.begin(i); element!=last; ++element ) {
162 element->value() *= scalar;
163 }
164 }
165 }
166
167 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
168
169 return *mat;
170}
171//*************************************************************************************************
172
173
174//*************************************************************************************************
187template< typename MT // Type of the left-hand side sparse matrix
188 , bool SO // Storage order
189 , typename ST > // Data type of the right-hand side scalar
190inline auto operator*=( SparseMatrix<MT,SO>&& mat, ST scalar )
192{
193 return operator*=( *mat, scalar );
194}
195//*************************************************************************************************
196
197
198//*************************************************************************************************
213template< typename MT // Type of the left-hand side sparse matrix
214 , bool SO // Storage order
215 , typename ST > // Data type of the right-hand side scalar
216inline auto operator/=( SparseMatrix<MT,SO>& mat, ST scalar )
218{
220
221 BLAZE_USER_ASSERT( !isZero( scalar ), "Division by zero detected" );
222
223 if( IsRestricted_v<MT> ) {
224 if( !tryDiv( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
225 BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
226 }
227 }
228
230 IsFloatingPoint_v< UnderlyingBuiltin_t<ST> >
231 , If_t< IsComplex_v< UnderlyingScalar_t<MT> > && IsBuiltin_v<ST>
234 , ST >;
235
236 decltype(auto) left( derestrict( *mat ) );
237
238 if( IsInvertible_v<ScalarType> ) {
239 const ScalarType tmp( ScalarType(1)/static_cast<ScalarType>( scalar ) );
240 const size_t iend( SO == rowMajor ? (*mat).rows() : (*mat).columns() );
241 for( size_t i=0UL; i<iend; ++i ) {
242 const auto last( left.end(i) );
243 for( auto element=left.begin(i); element!=last; ++element ) {
244 element->value() *= tmp;
245 }
246 }
247 }
248 else {
249 const size_t iend( SO == rowMajor ? (*mat).rows() : (*mat).columns() );
250 for( size_t i=0UL; i<iend; ++i ) {
251 const auto last( left.end(i) );
252 for( auto element=left.begin(i); element!=last; ++element ) {
253 element->value() /= scalar;
254 }
255 }
256 }
257
258 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
259
260 return *mat;
261}
262//*************************************************************************************************
263
264
265//*************************************************************************************************
280template< typename MT // Type of the left-hand side sparse matrix
281 , bool SO // Storage order
282 , typename ST > // Data type of the right-hand side scalar
283inline auto operator/=( SparseMatrix<MT,SO>&& mat, ST scalar )
285{
286 return operator/=( *mat, scalar );
287}
288//*************************************************************************************************
289
290
291
292
293//=================================================================================================
294//
295// GLOBAL FUNCTIONS
296//
297//=================================================================================================
298
299//*************************************************************************************************
302template< typename MT, bool SO >
303bool isnan( const SparseMatrix<MT,SO>& sm );
304
305template< typename MT, bool SO >
306bool isinf( const SparseMatrix<MT,SO>& sm );
307
308template< typename MT, bool SO >
309bool isfinite( const SparseMatrix<MT,SO>& sm );
310
311template< RelaxationFlag RF, typename MT, bool SO >
312bool isSymmetric( const SparseMatrix<MT,SO>& sm );
313
314template< RelaxationFlag RF, typename MT, bool SO >
315bool isHermitian( const SparseMatrix<MT,SO>& sm );
316
317template< RelaxationFlag RF, typename MT, bool SO >
318bool isUniform( const SparseMatrix<MT,SO>& sm );
319
320template< RelaxationFlag RF, typename MT, bool SO >
321bool isZero( const SparseMatrix<MT,SO>& sm );
322
323template< RelaxationFlag RF, typename MT, bool SO >
324bool isLower( const SparseMatrix<MT,SO>& sm );
325
326template< RelaxationFlag RF, typename MT, bool SO >
327bool isUniLower( const SparseMatrix<MT,SO>& sm );
328
329template< RelaxationFlag RF, typename MT, bool SO >
330bool isStrictlyLower( const SparseMatrix<MT,SO>& sm );
331
332template< RelaxationFlag RF, typename MT, bool SO >
333bool isUpper( const SparseMatrix<MT,SO>& sm );
334
335template< RelaxationFlag RF, typename MT, bool SO >
336bool isUniUpper( const SparseMatrix<MT,SO>& sm );
337
338template< RelaxationFlag RF, typename MT, bool SO >
339bool isStrictlyUpper( const SparseMatrix<MT,SO>& sm );
340
341template< RelaxationFlag RF, typename MT, bool SO >
342bool isDiagonal( const SparseMatrix<MT,SO>& sm );
343
344template< RelaxationFlag RF, typename MT, bool SO >
345bool isIdentity( const SparseMatrix<MT,SO>& sm );
347//*************************************************************************************************
348
349
350//*************************************************************************************************
367template< typename MT // Type of the sparse matrix
368 , bool SO > // Storage order
369bool isnan( const SparseMatrix<MT,SO>& sm )
370{
372 return false;
373
374 CompositeType_t<MT> A( *sm ); // Evaluation of the sparse matrix operand
375
376 if( SO == rowMajor ) {
377 for( size_t i=0UL; i<A.rows(); ++i ) {
378 for( auto element=A.begin(i); element!=A.end(i); ++element )
379 if( isnan( element->value() ) ) return true;
380 }
381 }
382 else {
383 for( size_t j=0UL; j<A.columns(); ++j ) {
384 for( auto element=A.begin(j); element!=A.end(j); ++element )
385 if( isnan( element->value() ) ) return true;
386 }
387 }
388
389 return false;
390}
391//*************************************************************************************************
392
393
394//*************************************************************************************************
411template< typename MT // Type of the sparse matrix
412 , bool SO > // Storage order
413bool isinf( const SparseMatrix<MT,SO>& sm )
414{
416 return false;
417
418 CompositeType_t<MT> A( *sm ); // Evaluation of the sparse matrix operand
419
420 if( SO == rowMajor ) {
421 for( size_t i=0UL; i<A.rows(); ++i ) {
422 for( auto element=A.begin(i); element!=A.end(i); ++element )
423 if( isinf( element->value() ) ) return true;
424 }
425 }
426 else {
427 for( size_t j=0UL; j<A.columns(); ++j ) {
428 for( auto element=A.begin(j); element!=A.end(j); ++element )
429 if( isinf( element->value() ) ) return true;
430 }
431 }
432
433 return false;
434}
435//*************************************************************************************************
436
437
438//*************************************************************************************************
455template< typename MT // Type of the sparse matrix
456 , bool SO > // Storage order
458{
460 return true;
461
462 CompositeType_t<MT> A( *sm ); // Evaluation of the sparse matrix operand
463
464 if( SO == rowMajor ) {
465 for( size_t i=0UL; i<A.rows(); ++i ) {
466 for( auto element=A.begin(i); element!=A.end(i); ++element )
467 if( !isfinite( element->value() ) ) return false;
468 }
469 }
470 else {
471 for( size_t j=0UL; j<A.columns(); ++j ) {
472 for( auto element=A.begin(j); element!=A.end(j); ++element )
473 if( !isfinite( element->value() ) ) return false;
474 }
475 }
476
477 return true;
478}
479//*************************************************************************************************
480
481
482//*************************************************************************************************
515template< RelaxationFlag RF // Relaxation flag
516 , typename MT // Type of the sparse matrix
517 , bool SO > // Storage order
519{
520 using RT = ResultType_t<MT>;
521 using RN = ReturnType_t<MT>;
522 using CT = CompositeType_t<MT>;
523 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
524
525 if( IsSymmetric_v<MT> )
526 return true;
527
528 if( !isSquare( *sm ) )
529 return false;
530
531 if( IsUniform_v<MT> || (*sm).rows() < 2UL )
532 return true;
533
534 Tmp A( *sm ); // Evaluation of the sparse matrix operand
535
536 if( SO == rowMajor ) {
537 for( size_t i=0UL; i<A.rows(); ++i ) {
538 for( auto element=A.begin(i); element!=A.end(i); ++element )
539 {
540 const size_t j( element->index() );
541
542 if( i == j || isDefault<RF>( element->value() ) )
543 continue;
544
545 const auto pos( A.find( j, i ) );
546 if( pos == A.end(j) || !equal<RF>( pos->value(), element->value() ) )
547 return false;
548 }
549 }
550 }
551 else {
552 for( size_t j=0UL; j<A.columns(); ++j ) {
553 for( auto element=A.begin(j); element!=A.end(j); ++element )
554 {
555 const size_t i( element->index() );
556
557 if( j == i || isDefault<RF>( element->value() ) )
558 continue;
559
560 const auto pos( A.find( j, i ) );
561 if( pos == A.end(i) || !equal<RF>( pos->value(), element->value() ) )
562 return false;
563 }
564 }
565 }
566
567 return true;
568}
569//*************************************************************************************************
570
571
572//*************************************************************************************************
607template< RelaxationFlag RF // Relaxation flag
608 , typename MT // Type of the sparse matrix
609 , bool SO > // Storage order
611{
612 using RT = ResultType_t<MT>;
613 using ET = ElementType_t<MT>;
614 using RN = ReturnType_t<MT>;
615 using CT = CompositeType_t<MT>;
616 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
617
618 if( IsHermitian_v<MT> )
619 return true;
620
621 if( !IsScalar_v<ET> || !isSquare( *sm ) )
622 return false;
623
624 if( IsBuiltin_v<ET> && IsUniform_v<MT> )
625 return true;
626
627 Tmp A( *sm ); // Evaluation of the sparse matrix operand
628
629 if( SO == rowMajor ) {
630 for( size_t i=0UL; i<A.rows(); ++i ) {
631 for( auto element=A.begin(i); element!=A.end(i); ++element )
632 {
633 const size_t j( element->index() );
634
635 if( isDefault<RF>( element->value() ) )
636 continue;
637
638 if( i == j && !isReal<RF>( element->value() ) )
639 return false;
640
641 const auto pos( A.find( j, i ) );
642 if( pos == A.end(j) || !equal<RF>( pos->value(), conj( element->value() ) ) )
643 return false;
644 }
645 }
646 }
647 else {
648 for( size_t j=0UL; j<A.columns(); ++j ) {
649 for( auto element=A.begin(j); element!=A.end(j); ++element )
650 {
651 const size_t i( element->index() );
652
653 if( isDefault<RF>( element->value() ) )
654 continue;
655
656 if( j == i && !isReal<RF>( element->value() ) )
657 return false;
658
659 const auto pos( A.find( j, i ) );
660 if( pos == A.end(i) || !equal<RF>( pos->value(), conj( element->value() ) ) )
661 return false;
662 }
663 }
664 }
665
666 return true;
667}
668//*************************************************************************************************
669
670
671//*************************************************************************************************
679template< RelaxationFlag RF // Relaxation flag
680 , typename MT > // Type of the sparse matrix
681bool isUniform_backend( const SparseMatrix<MT,false>& sm, TrueType )
682{
685
686 BLAZE_INTERNAL_ASSERT( (*sm).rows() != 0UL, "Invalid number of rows detected" );
687 BLAZE_INTERNAL_ASSERT( (*sm).columns() != 0UL, "Invalid number of columns detected" );
688
689 const size_t ibegin( ( IsStrictlyLower_v<MT> )?( 1UL ):( 0UL ) );
690 const size_t iend ( ( IsStrictlyUpper_v<MT> )?( (*sm).rows()-1UL ):( (*sm).rows() ) );
691
692 for( size_t i=ibegin; i<iend; ++i ) {
693 for( auto element=(*sm).begin(i); element!=(*sm).end(i); ++element ) {
694 if( !isDefault<RF>( element->value() ) )
695 return false;
696 }
697 }
698
699 return true;
700}
702//*************************************************************************************************
703
704
705//*************************************************************************************************
713template< RelaxationFlag RF // Relaxation flag
714 , typename MT > // Type of the sparse matrix
715bool isUniform_backend( const SparseMatrix<MT,true>& sm, TrueType )
716{
719
720 BLAZE_INTERNAL_ASSERT( (*sm).rows() != 0UL, "Invalid number of rows detected" );
721 BLAZE_INTERNAL_ASSERT( (*sm).columns() != 0UL, "Invalid number of columns detected" );
722
723 const size_t jbegin( ( IsStrictlyUpper_v<MT> )?( 1UL ):( 0UL ) );
724 const size_t jend ( ( IsStrictlyLower_v<MT> )?( (*sm).columns()-1UL ):( (*sm).columns() ) );
725
726 for( size_t j=jbegin; j<jend; ++j ) {
727 for( auto element=(*sm).begin(j); element!=(*sm).end(j); ++element ) {
728 if( !isDefault<RF>( element->value() ) )
729 return false;
730 }
731 }
732
733 return true;
734}
736//*************************************************************************************************
737
738
739//*************************************************************************************************
747template< RelaxationFlag RF // Relaxation flag
748 , typename MT > // Type of the sparse matrix
749bool isUniform_backend( const SparseMatrix<MT,false>& sm, FalseType )
750{
753
754 BLAZE_INTERNAL_ASSERT( (*sm).rows() != 0UL, "Invalid number of rows detected" );
755 BLAZE_INTERNAL_ASSERT( (*sm).columns() != 0UL, "Invalid number of columns detected" );
756
757 const size_t maxElements( (*sm).rows() * (*sm).columns() );
758
759 if( (*sm).nonZeros() != maxElements )
760 {
761 for( size_t i=0UL; i<(*sm).rows(); ++i ) {
762 for( auto element=(*sm).begin(i); element!=(*sm).end(i); ++element ) {
763 if( !isDefault<RF>( element->value() ) )
764 return false;
765 }
766 }
767 }
768 else
769 {
770 BLAZE_INTERNAL_ASSERT( (*sm).find(0UL,0UL) != (*sm).end(0UL), "Missing element detected" );
771
772 const auto& cmp( (*sm)(0UL,0UL) );
773
774 for( size_t i=0UL; i<(*sm).rows(); ++i ) {
775 for( auto element=(*sm).begin(i); element!=(*sm).end(i); ++element ) {
776 if( !equal<RF>( element->value(), cmp ) )
777 return false;
778 }
779 }
780 }
781
782 return true;
783}
785//*************************************************************************************************
786
787
788//*************************************************************************************************
796template< RelaxationFlag RF // Relaxation flag
797 , typename MT > // Type of the sparse matrix
798bool isUniform_backend( const SparseMatrix<MT,true>& sm, FalseType )
799{
802
803 BLAZE_INTERNAL_ASSERT( (*sm).rows() != 0UL, "Invalid number of rows detected" );
804 BLAZE_INTERNAL_ASSERT( (*sm).columns() != 0UL, "Invalid number of columns detected" );
805
806 const size_t maxElements( (*sm).rows() * (*sm).columns() );
807
808 if( (*sm).nonZeros() != maxElements )
809 {
810 for( size_t j=0UL; j<(*sm).columns(); ++j ) {
811 for( auto element=(*sm).begin(j); element!=(*sm).end(j); ++element ) {
812 if( !isDefault<RF>( element->value() ) )
813 return false;
814 }
815 }
816 }
817 else
818 {
819 BLAZE_INTERNAL_ASSERT( (*sm).find(0UL,0UL) != (*sm).end(0UL), "Missing element detected" );
820
821 const auto& cmp( (*sm)(0UL,0UL) );
822
823 for( size_t j=0UL; j<(*sm).columns(); ++j ) {
824 for( auto element=(*sm).begin(j); element!=(*sm).end(j); ++element ) {
825 if( !equal<RF>( element->value(), cmp ) )
826 return false;
827 }
828 }
829 }
830
831 return true;
832}
834//*************************************************************************************************
835
836
837//*************************************************************************************************
870template< RelaxationFlag RF // Relaxation flag
871 , typename MT // Type of the sparse matrix
872 , bool SO > // Storage order
874{
875 if( IsUniform_v<MT> ||
876 (*sm).rows() == 0UL || (*sm).columns() == 0UL ||
877 ( (*sm).rows() == 1UL && (*sm).columns() == 1UL ) )
878 return true;
879
880 if( IsUniTriangular_v<MT> )
881 return false;
882
883 CompositeType_t<MT> A( *sm ); // Evaluation of the sparse matrix operand
884
885 return isUniform_backend<RF>( A, typename IsTriangular<MT>::Type() );
886}
887//*************************************************************************************************
888
889
890//*************************************************************************************************
923template< RelaxationFlag RF // Relaxation flag
924 , typename MT // Type of the sparse matrix
925 , bool SO > // Storage order
927{
928 const size_t M( (*sm).rows() );
929 const size_t N( (*sm).columns() );
930
931 if( IsZero_v<MT> || M == 0UL || N == 0UL )
932 return true;
933
934 if( IsUniTriangular_v<MT> )
935 return false;
936
937 CompositeType_t<MT> A( *sm ); // Evaluation of the sparse matrix operand
938
939 const size_t iend( SO == rowMajor ? A.rows() : A.columns() );
940
941 for( size_t i=0UL; i<iend; ++i ) {
942 for( auto element=A.begin(i); element!=A.end(i); ++element ) {
943 if( !isZero<RF>( element->value() ) ) {
944 return false;
945 }
946 }
947 }
948
949 return true;
950}
951//*************************************************************************************************
952
953
954//*************************************************************************************************
997template< RelaxationFlag RF // Relaxation flag
998 , typename MT // Type of the sparse matrix
999 , bool SO > // Storage order
1001{
1002 using RT = ResultType_t<MT>;
1003 using RN = ReturnType_t<MT>;
1004 using CT = CompositeType_t<MT>;
1005 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1006
1007 if( IsLower_v<MT> )
1008 return true;
1009
1010 if( !isSquare( *sm ) )
1011 return false;
1012
1013 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1014 return true;
1015
1016 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1017
1018 if( SO == rowMajor ) {
1019 for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
1020 for( auto element=A.lowerBound(i,i+1UL); element!=A.end(i); ++element )
1021 {
1022 if( !isDefault<RF>( element->value() ) )
1023 return false;
1024 }
1025 }
1026 }
1027 else {
1028 for( size_t j=1UL; j<A.columns(); ++j ) {
1029 for( auto element=A.begin(j); element!=A.end(j); ++element )
1030 {
1031 if( element->index() >= j )
1032 break;
1033
1034 if( !isDefault<RF>( element->value() ) )
1035 return false;
1036 }
1037 }
1038 }
1039
1040 return true;
1041}
1042//*************************************************************************************************
1043
1044
1045//*************************************************************************************************
1087template< RelaxationFlag RF // Relaxation flag
1088 , typename MT // Type of the sparse matrix
1089 , bool SO > // Storage order
1091{
1092 using RT = ResultType_t<MT>;
1093 using RN = ReturnType_t<MT>;
1094 using CT = CompositeType_t<MT>;
1095 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1096
1097 if( IsUniLower_v<MT> )
1098 return true;
1099
1100 if( !isSquare( *sm ) )
1101 return false;
1102
1103 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1104
1105 if( SO == rowMajor ) {
1106 for( size_t i=0UL; i<A.rows(); ++i )
1107 {
1108 auto element( A.lowerBound(i,i) );
1109
1110 if( element == A.end(i) || element->index() != i || !isOne<RF>( element->value() ) )
1111 return false;
1112
1113 ++element;
1114
1115 for( ; element!=A.end(i); ++element ) {
1116 if( !isZero<RF>( element->value() ) )
1117 return false;
1118 }
1119 }
1120 }
1121 else {
1122 for( size_t j=0UL; j<A.columns(); ++j )
1123 {
1124 bool hasDiagonalElement( false );
1125
1126 for( auto element=A.begin(j); element!=A.end(j); ++element )
1127 {
1128 if( element->index() >= j ) {
1129 if( element->index() != j || !isOne<RF>( element->value() ) )
1130 return false;
1131 hasDiagonalElement = true;
1132 break;
1133 }
1134
1135 if( !isZero<RF>( element->value() ) )
1136 return false;
1137 }
1138
1139 if( !hasDiagonalElement ) {
1140 return false;
1141 }
1142 }
1143 }
1144
1145 return true;
1146}
1147//*************************************************************************************************
1148
1149
1150//*************************************************************************************************
1193template< RelaxationFlag RF // Relaxation flag
1194 , typename MT // Type of the sparse matrix
1195 , bool SO > // Storage order
1197{
1198 using RT = ResultType_t<MT>;
1199 using RN = ReturnType_t<MT>;
1200 using CT = CompositeType_t<MT>;
1201 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1202
1203 if( IsStrictlyLower_v<MT> )
1204 return true;
1205
1206 if( !isSquare( *sm ) )
1207 return false;
1208
1209 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1210 return true;
1211
1212 if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1213 return false;
1214
1215 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1216
1217 if( SO == rowMajor ) {
1218 for( size_t i=0UL; i<A.rows(); ++i ) {
1219 for( auto element=A.lowerBound(i,i); element!=A.end(i); ++element )
1220 {
1221 if( !isDefault<RF>( element->value() ) )
1222 return false;
1223 }
1224 }
1225 }
1226 else {
1227 for( size_t j=0UL; j<A.columns(); ++j ) {
1228 for( auto element=A.begin(j); element!=A.end(j); ++element )
1229 {
1230 if( element->index() > j )
1231 break;
1232
1233 if( !isDefault<RF>( element->value() ) )
1234 return false;
1235 }
1236 }
1237 }
1238
1239 return true;
1240}
1241//*************************************************************************************************
1242
1243
1244//*************************************************************************************************
1287template< RelaxationFlag RF // Relaxation flag
1288 , typename MT // Type of the sparse matrix
1289 , bool SO > // Storage order
1291{
1292 using RT = ResultType_t<MT>;
1293 using RN = ReturnType_t<MT>;
1294 using CT = CompositeType_t<MT>;
1295 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1296
1297 if( IsUpper_v<MT> )
1298 return true;
1299
1300 if( !isSquare( *sm ) )
1301 return false;
1302
1303 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1304 return true;
1305
1306 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1307
1308 if( SO == rowMajor ) {
1309 for( size_t i=1UL; i<A.rows(); ++i ) {
1310 for( auto element=A.begin(i); element!=A.end(i); ++element )
1311 {
1312 if( element->index() >= i )
1313 break;
1314
1315 if( !isDefault<RF>( element->value() ) )
1316 return false;
1317 }
1318 }
1319 }
1320 else {
1321 for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
1322 for( auto element=A.lowerBound(j+1UL,j); element!=A.end(j); ++element )
1323 {
1324 if( !isDefault<RF>( element->value() ) )
1325 return false;
1326 }
1327 }
1328 }
1329
1330 return true;
1331}
1332//*************************************************************************************************
1333
1334
1335//*************************************************************************************************
1377template< RelaxationFlag RF // Relaxation flag
1378 , typename MT // Type of the sparse matrix
1379 , bool SO > // Storage order
1381{
1382 using RT = ResultType_t<MT>;
1383 using RN = ReturnType_t<MT>;
1384 using CT = CompositeType_t<MT>;
1385 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1386
1387 if( IsUniUpper_v<MT> )
1388 return true;
1389
1390 if( !isSquare( *sm ) )
1391 return false;
1392
1393 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1394
1395 if( SO == rowMajor ) {
1396 for( size_t i=0UL; i<A.rows(); ++i )
1397 {
1398 bool hasDiagonalElement( false );
1399
1400 for( auto element=A.begin(i); element!=A.end(i); ++element )
1401 {
1402 if( element->index() >= i ) {
1403 if( element->index() != i || !isOne<RF>( element->value() ) )
1404 return false;
1405 hasDiagonalElement = true;
1406 break;
1407 }
1408 else if( !isZero<RF>( element->value() ) ) {
1409 return false;
1410 }
1411 }
1412
1413 if( !hasDiagonalElement ) {
1414 return false;
1415 }
1416 }
1417 }
1418 else {
1419 for( size_t j=0UL; j<A.columns(); ++j )
1420 {
1421 auto element( A.lowerBound(j,j) );
1422
1423 if( element == A.end(j) || element->index() != j || !isOne<RF>( element->value() ) )
1424 return false;
1425
1426 ++element;
1427
1428 for( ; element!=A.end(j); ++element ) {
1429 if( !isZero<RF>( element->value() ) )
1430 return false;
1431 }
1432 }
1433 }
1434
1435 return true;
1436}
1437//*************************************************************************************************
1438
1439
1440//*************************************************************************************************
1483template< RelaxationFlag RF // Relaxation flag
1484 , typename MT // Type of the sparse matrix
1485 , bool SO > // Storage order
1487{
1488 using RT = ResultType_t<MT>;
1489 using RN = ReturnType_t<MT>;
1490 using CT = CompositeType_t<MT>;
1491 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1492
1493 if( IsStrictlyUpper_v<MT> )
1494 return true;
1495
1496 if( !isSquare( *sm ) )
1497 return false;
1498
1499 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1500 return true;
1501
1502 if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1503 return false;
1504
1505 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1506
1507 if( SO == rowMajor ) {
1508 for( size_t i=0UL; i<A.rows(); ++i ) {
1509 for( auto element=A.begin(i); element!=A.end(i); ++element )
1510 {
1511 if( element->index() > i )
1512 break;
1513
1514 if( !isDefault<RF>( element->value() ) )
1515 return false;
1516 }
1517 }
1518 }
1519 else {
1520 for( size_t j=0UL; j<A.columns(); ++j ) {
1521 for( auto element=A.lowerBound(j,j); element!=A.end(j); ++element )
1522 {
1523 if( !isDefault<RF>( element->value() ) )
1524 return false;
1525 }
1526 }
1527 }
1528
1529 return true;
1530}
1531//*************************************************************************************************
1532
1533
1534//*************************************************************************************************
1577template< RelaxationFlag RF // Relaxation flag
1578 , typename MT // Type of the sparse matrix
1579 , bool SO > // Storage order
1581{
1582 using RT = ResultType_t<MT>;
1583 using RN = ReturnType_t<MT>;
1584 using CT = CompositeType_t<MT>;
1585 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1586
1587 if( IsDiagonal_v<MT> )
1588 return true;
1589
1590 if( !isSquare( *sm ) )
1591 return false;
1592
1593 if( IsZero_v<MT> || (*sm).rows() < 2UL )
1594 return true;
1595
1596 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1597
1598 if( SO == rowMajor ) {
1599 for( size_t i=0UL; i<A.rows(); ++i ) {
1600 for( auto element=A.begin(i); element!=A.end(i); ++element )
1601 if( element->index() != i && !isDefault<RF>( element->value() ) )
1602 return false;
1603 }
1604 }
1605 else {
1606 for( size_t j=0UL; j<A.columns(); ++j ) {
1607 for( auto element=A.begin(j); element!=A.end(j); ++element )
1608 if( element->index() != j && !isDefault<RF>( element->value() ) )
1609 return false;
1610 }
1611 }
1612
1613 return true;
1614}
1615//*************************************************************************************************
1616
1617
1618//*************************************************************************************************
1661template< RelaxationFlag RF // Relaxation flag
1662 , typename MT // Type of the sparse matrix
1663 , bool SO > // Storage order
1665{
1666 using RT = ResultType_t<MT>;
1667 using RN = ReturnType_t<MT>;
1668 using CT = CompositeType_t<MT>;
1669 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1670
1671 if( IsIdentity_v<MT> )
1672 return true;
1673
1674 if( !isSquare( *sm ) )
1675 return false;
1676
1677 Tmp A( *sm ); // Evaluation of the sparse matrix operand
1678
1679 if( SO == rowMajor ) {
1680 for( size_t i=0UL; i<A.rows(); ++i )
1681 {
1682 bool hasDiagonalElement( false );
1683
1684 for( auto element=A.begin(i); element!=A.end(i); ++element )
1685 {
1686 if( element->index() == i ) {
1687 if( !isOne<RF>( element->value() ) )
1688 return false;
1689 hasDiagonalElement = true;
1690 }
1691 else if( !isZero<RF>( element->value() ) ) {
1692 return false;
1693 }
1694 }
1695
1696 if( !hasDiagonalElement ) {
1697 return false;
1698 }
1699 }
1700 }
1701 else {
1702 for( size_t j=0UL; j<A.columns(); ++j )
1703 {
1704 bool hasDiagonalElement( false );
1705
1706 for( auto element=A.begin(j); element!=A.end(j); ++element )
1707 {
1708 if( element->index() == j ) {
1709 if( !isOne<RF>( element->value() ) )
1710 return false;
1711 hasDiagonalElement = true;
1712 }
1713 else if( !isZero<RF>( element->value() ) ) {
1714 return false;
1715 }
1716 }
1717
1718 if( !hasDiagonalElement ) {
1719 return false;
1720 }
1721 }
1722 }
1723
1724 return true;
1725}
1726//*************************************************************************************************
1727
1728
1729//*************************************************************************************************
1743template< typename MT // Type of the sparse matrix
1744 , bool SO // Storage order
1745 , typename... Args > // Type of the erase arguments
1746auto erase( SparseMatrix<MT,SO>& sm, Args&&... args )
1747 -> decltype( (*sm).erase( std::forward<Args>( args )... ) )
1748{
1749 return (*sm).erase( std::forward<Args>( args )... );
1750}
1752//*************************************************************************************************
1753
1754} // namespace blaze
1755
1756#endif
Header file for auxiliary alias declarations.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.
Definition: Aliases.h:110
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.
Definition: Aliases.h:470
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.
Definition: Aliases.h:450
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for run time assertion macros.
Header file for the conjugate shim.
Header file for the division trait.
Header file for the EnableIf class template.
Header file for the If class template.
Header file for the IntegralConstant class template.
Header file for the IsBuiltin type trait.
Header file for the IsComplex type trait.
Header file for the isDefault shim.
Header file for the IsDiagonal type trait.
Header file for the IsExpression type trait class.
Header file for the isfinite shim.
Header file for the IsFloatingPoint type trait.
Header file for the IsHermitian type trait.
Header file for the IsIdentity type trait.
Header file for the isinf shim.
Header file for the IsInvertible type trait.
Header file for the IsLower type trait.
Header file for the isnan shim.
Header file for the isOne shim.
Header file for the isReal shim.
Header file for the IsResizable type trait.
Header file for the IsRestricted type trait.
Header file for the IsScalar type trait.
Header file for the IsSquare type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Header file for the IsTriangular type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniTriangular type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUniform type trait.
Header file for the IsUpper type trait.
Header file for the relaxation flag enumeration.
Constraint on the data type.
Header file for the UnderlyingBuiltin type trait.
Header file for the UnderlyingScalar type trait.
Constraint on the data type.
Base class for sparse matrices.
Definition: SparseMatrix.h:77
Constraint on the data type.
Header file for the SparseMatrix base class.
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1464
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Triangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Triangular.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
typename DivTrait< T1, T2 >::Type DivTrait_t
Auxiliary alias declaration for the DivTrait class template.
Definition: DivTrait.h:164
typename UnderlyingBuiltin< T >::Type UnderlyingBuiltin_t
Auxiliary alias declaration for the UnderlyingBuiltin type trait.
Definition: UnderlyingBuiltin.h:117
constexpr bool IsResizable_v
Auxiliary variable template for the IsResizable type trait.
Definition: IsResizable.h:136
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:1383
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
bool isZero(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a zero matrix.
Definition: SparseMatrix.h:926
bool isUniLower(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a lower unitriangular matrix.
Definition: SparseMatrix.h:1090
auto operator/=(SparseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a temporary sparse matrix by a scalar value ( ).
Definition: SparseMatrix.h:283
bool isfinite(const SparseMatrix< MT, SO > &sm)
Checks the given sparse matrix for finite elements.
Definition: SparseMatrix.h:457
bool isnan(const SparseMatrix< MT, SO > &sm)
Checks the given sparse matrix for not-a-number elements.
Definition: SparseMatrix.h:369
bool isDiagonal(const SparseMatrix< MT, SO > &sm)
Checks if the give sparse matrix is diagonal.
Definition: SparseMatrix.h:1580
bool isUniUpper(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is an upper unitriangular matrix.
Definition: SparseMatrix.h:1380
bool isIdentity(const SparseMatrix< MT, SO > &sm)
Checks if the give sparse matrix is an identity matrix.
Definition: SparseMatrix.h:1664
auto operator*=(SparseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a temporary sparse matrix and a scalar v...
Definition: SparseMatrix.h:190
bool isinf(const SparseMatrix< MT, SO > &sm)
Checks the given sparse matrix for infinite elements.
Definition: SparseMatrix.h:413
bool isHermitian(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is Hermitian.
Definition: SparseMatrix.h:610
bool isUniform(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a uniform matrix.
Definition: SparseMatrix.h:873
bool isLower(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a lower triangular matrix.
Definition: SparseMatrix.h:1000
bool isStrictlyLower(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a strictly lower triangular matrix.
Definition: SparseMatrix.h:1196
bool isStrictlyUpper(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is a strictly upper triangular matrix.
Definition: SparseMatrix.h:1486
bool isSymmetric(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is symmetric.
Definition: SparseMatrix.h:518
bool isUpper(const SparseMatrix< MT, SO > &sm)
Checks if the given sparse matrix is an upper triangular matrix.
Definition: SparseMatrix.h:1290
constexpr bool IsFloatingPoint_v
Auxiliary variable template for the IsFloatingPoint type trait.
Definition: IsFloatingPoint.h:95
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
BoolConstant< false > FalseType
Type/value traits base class.
Definition: IntegralConstant.h:121
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
typename If< Condition >::template Type< T1, T2 > If_t
Auxiliary alias template for the If class template.
Definition: If.h:108
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the matrix storage order types.
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Header file for the equal shim.
Header file for the isZero shim.
Compile time check for triangular matrix types.
Definition: IsTriangular.h:88
Header file for the IsZero type trait.
Header file for basic type definitions.