Blaze 3.9
DenseMatrix.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_DENSE_DENSEMATRIX_H_
36#define _BLAZE_MATH_DENSE_DENSEMATRIX_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <algorithm>
44#include <blaze/math/Aliases.h>
50#include <blaze/math/Epsilon.h>
88#include <blaze/util/Assert.h>
89#include <blaze/util/EnableIf.h>
91#include <blaze/util/Limits.h>
92#include <blaze/util/mpl/If.h>
94#include <blaze/util/Types.h>
97
98
99namespace blaze {
100
101//=================================================================================================
102//
103// GLOBAL OPERATORS
104//
105//=================================================================================================
106
107//*************************************************************************************************
110template< typename T1, typename T2 >
111auto operator==( const DenseMatrix<T1,false>& mat, T2 scalar )
112 -> EnableIf_t< IsScalar_v<T2>, bool >;
113
114template< typename T1, typename T2 >
115auto operator==( const DenseMatrix<T1,true>& mat, T2 scalar )
116 -> EnableIf_t< IsScalar_v<T2>, bool >;
117
118template< typename T1, typename T2, bool SO >
119auto operator==( T1 scalar, const DenseMatrix<T2,SO>& mat )
120 -> EnableIf_t< IsScalar_v<T2>, bool >;
121
122template< typename T1, typename T2, bool SO >
123auto operator!=( const DenseMatrix<T1,SO>& mat, T2 scalar )
124 -> EnableIf_t< IsScalar_v<T2>, bool >;
125
126template< typename T1, typename T2, bool SO >
127auto operator!=( T1 scalar, const DenseMatrix<T2,SO>& mat )
128 -> EnableIf_t< IsScalar_v<T2>, bool >;
129
130template< typename MT, bool SO, typename ST >
131auto operator+=( DenseMatrix<MT,SO>& mat, ST scalar )
132 -> EnableIf_t< IsScalar_v<ST>, MT& >;
133
134template< typename MT, bool SO, typename ST >
135auto operator+=( DenseMatrix<MT,SO>&& mat, ST scalar )
136 -> EnableIf_t< IsScalar_v<ST>, MT& >;
137
138template< typename MT, bool SO, typename ST >
139auto operator-=( DenseMatrix<MT,SO>& mat, ST scalar )
140 -> EnableIf_t< IsScalar_v<ST>, MT& >;
141
142template< typename MT, bool SO, typename ST >
143auto operator-=( DenseMatrix<MT,SO>&& mat, ST scalar )
144 -> EnableIf_t< IsScalar_v<ST>, MT& >;
145
146template< typename MT, bool SO, typename ST >
147auto operator*=( DenseMatrix<MT,SO>& mat, ST scalar )
148 -> EnableIf_t< IsScalar_v<ST>, MT& >;
149
150template< typename MT, bool SO, typename ST >
151auto operator*=( DenseMatrix<MT,SO>&& mat, ST scalar )
152 -> EnableIf_t< IsScalar_v<ST>, MT& >;
153
154template< typename MT, bool SO, typename ST >
155auto operator/=( DenseMatrix<MT,SO>& mat, ST scalar )
156 -> EnableIf_t< IsScalar_v<ST>, MT& >;
157
158template< typename MT, bool SO, typename ST >
159auto operator/=( DenseMatrix<MT,SO>&& mat, ST scalar )
160 -> EnableIf_t< IsScalar_v<ST>, MT& >;
161
162template< typename MT, bool SO >
163MT& operator<<=( DenseMatrix<MT,SO>& mat, int count );
164
165template< typename MT, bool SO >
166MT& operator<<=( DenseMatrix<MT,SO>&& mat, int count );
167
168template< typename MT1, bool SO1, typename MT2, bool SO2 >
169MT1& operator<<=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
170
171template< typename MT1, bool SO1, typename MT2, bool SO2 >
172MT1& operator<<=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
173
174template< typename MT, bool SO >
175MT& operator>>=( DenseMatrix<MT,SO>& mat, int count );
176
177template< typename MT, bool SO >
178MT& operator>>=( DenseMatrix<MT,SO>&& mat, int count );
179
180template< typename MT1, bool SO1, typename MT2, bool SO2 >
181MT1& operator>>=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
182
183template< typename MT1, bool SO1, typename MT2, bool SO2 >
184MT1& operator>>=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
185
186template< typename MT, bool SO, typename ST >
187auto operator&=( DenseMatrix<MT,SO>& mat, ST scalar )
188 -> EnableIf_t< IsScalar_v<ST>, MT& >;
189
190template< typename MT, bool SO, typename ST >
191auto operator&=( DenseMatrix<MT,SO>&& mat, ST scalar )
192 -> EnableIf_t< IsScalar_v<ST>, MT& >;
193
194template< typename MT1, bool SO1, typename MT2, bool SO2 >
195MT1& operator&=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
196
197template< typename MT1, bool SO1, typename MT2, bool SO2 >
198MT1& operator&=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
199
200template< typename MT, bool SO, typename ST >
201auto operator|=( DenseMatrix<MT,SO>& mat, ST scalar )
202 -> EnableIf_t< IsScalar_v<ST>, MT& >;
203
204template< typename MT, bool SO, typename ST >
205auto operator|=( DenseMatrix<MT,SO>&& mat, ST scalar )
206 -> EnableIf_t< IsScalar_v<ST>, MT& >;
207
208template< typename MT1, bool SO1, typename MT2, bool SO2 >
209MT1& operator|=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
210
211template< typename MT1, bool SO1, typename MT2, bool SO2 >
212MT1& operator|=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
213
214template< typename MT, bool SO, typename ST >
215auto operator^=( DenseMatrix<MT,SO>& mat, ST scalar )
216 -> EnableIf_t< IsScalar_v<ST>, MT& >;
217
218template< typename MT, bool SO, typename ST >
219auto operator^=( DenseMatrix<MT,SO>&& mat, ST scalar )
220 -> EnableIf_t< IsScalar_v<ST>, MT& >;
221
222template< typename MT1, bool SO1, typename MT2, bool SO2 >
223MT1& operator^=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
224
225template< typename MT1, bool SO1, typename MT2, bool SO2 >
226MT1& operator^=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
228//*************************************************************************************************
229
230
231//*************************************************************************************************
243template< typename T1 // Type of the left-hand side dense matrix
244 , typename T2 > // Type of the right-hand side scalar
245inline auto operator==( const DenseMatrix<T1,false>& mat, T2 scalar )
247{
248 using CT1 = CompositeType_t<T1>;
249
250 // Evaluation of the dense matrix operand
251 CT1 A( *mat );
252
253 // In order to compare the matrix and the scalar value, the data values of the lower-order
254 // data type are converted to the higher-order data type within the equal function.
255 for( size_t i=0; i<A.rows(); ++i ) {
256 for( size_t j=0; j<A.columns(); ++j ) {
257 if( !equal( A(i,j), scalar ) ) return false;
258 }
259 }
260
261 return true;
262}
263//*************************************************************************************************
264
265
266//*************************************************************************************************
278template< typename T1 // Type of the left-hand side dense matrix
279 , typename T2 > // Type of the right-hand side scalar
280inline auto operator==( const DenseMatrix<T1,true>& mat, T2 scalar )
282{
283 using CT1 = CompositeType_t<T1>;
284
285 // Evaluation of the dense matrix operand
286 CT1 A( *mat );
287
288 // In order to compare the matrix and the scalar value, the data values of the lower-order
289 // data type are converted to the higher-order data type within the equal function.
290 for( size_t j=0; j<A.columns(); ++j ) {
291 for( size_t i=0; i<A.rows(); ++i ) {
292 if( !equal( A(i,j), scalar ) ) return false;
293 }
294 }
295
296 return true;
297}
298//*************************************************************************************************
299
300
301//*************************************************************************************************
313template< typename T1 // Type of the left-hand side scalar
314 , typename T2 // Type of the right-hand side dense matrix
315 , bool SO > // Storage order
316inline auto operator==( T1 scalar, const DenseMatrix<T2,SO>& mat )
318{
319 return ( mat == scalar );
320}
321//*************************************************************************************************
322
323
324//*************************************************************************************************
336template< typename T1 // Type of the left-hand side dense matrix
337 , typename T2 // Type of the right-hand side scalar
338 , bool SO > // Storage order
339inline auto operator!=( const DenseMatrix<T1,SO>& mat, T2 scalar )
341{
342 return !( mat == scalar );
343}
344//*************************************************************************************************
345
346
347//*************************************************************************************************
359template< typename T1 // Type of the left-hand side scalar
360 , typename T2 // Type of the right-hand side dense matrix
361 , bool SO > // Storage order
362inline auto operator!=( T1 scalar, const DenseMatrix<T2,SO>& mat )
364{
365 return !( mat == scalar );
366}
367//*************************************************************************************************
368
369
370//*************************************************************************************************
383template< typename MT // Type of the left-hand side dense matrix
384 , bool SO // Storage order
385 , typename ST > // Data type of the right-hand side scalar
386inline auto operator+=( DenseMatrix<MT,SO>& mat, ST scalar )
388{
390
391 if( IsRestricted_v<MT> ) {
392 if( !tryAdd( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
393 BLAZE_THROW_INVALID_ARGUMENT( "Invalid addition to restricted matrix" );
394 }
395 }
396
397 decltype(auto) left( derestrict( *mat ) );
398
399 smpAssign( left, left + scalar );
400
401 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
402
403 return *mat;
404}
405//*************************************************************************************************
406
407
408//*************************************************************************************************
421template< typename MT // Type of the left-hand side dense matrix
422 , bool SO // Storage order
423 , typename ST > // Data type of the right-hand side scalar
424inline auto operator+=( DenseMatrix<MT,SO>&& mat, ST scalar )
426{
427 return operator+=( *mat, scalar );
428}
429//*************************************************************************************************
430
431
432//*************************************************************************************************
445template< typename MT // Type of the left-hand side dense matrix
446 , bool SO // Storage order
447 , typename ST > // Data type of the right-hand side scalar
448inline auto operator-=( DenseMatrix<MT,SO>& mat, ST scalar )
450{
452
453 if( IsRestricted_v<MT> ) {
454 if( !trySub( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
455 BLAZE_THROW_INVALID_ARGUMENT( "Invalid subtraction from restricted matrix" );
456 }
457 }
458
459 decltype(auto) left( derestrict( *mat ) );
460
461 smpAssign( left, left - scalar );
462
463 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
464
465 return *mat;
466}
467//*************************************************************************************************
468
469
470//*************************************************************************************************
483template< typename MT // Type of the left-hand side dense matrix
484 , bool SO // Storage order
485 , typename ST > // Data type of the right-hand side scalar
486inline auto operator-=( DenseMatrix<MT,SO>&& mat, ST scalar )
488{
489 return operator-=( *mat, scalar );
490}
491//*************************************************************************************************
492
493
494//*************************************************************************************************
507template< typename MT // Type of the left-hand side dense matrix
508 , bool SO // Storage order
509 , typename ST > // Data type of the right-hand side scalar
510inline auto operator*=( DenseMatrix<MT,SO>& mat, ST scalar )
512{
514
515 if( IsRestricted_v<MT> ) {
516 if( !tryMult( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
517 BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
518 }
519 }
520
521 decltype(auto) left( derestrict( *mat ) );
522
523 smpAssign( left, left * scalar );
524
525 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
526
527 return *mat;
528}
529//*************************************************************************************************
530
531
532//*************************************************************************************************
545template< typename MT // Type of the left-hand side dense matrix
546 , bool SO // Storage order
547 , typename ST > // Data type of the right-hand side scalar
548inline auto operator*=( DenseMatrix<MT,SO>&& mat, ST scalar )
550{
551 return operator*=( *mat, scalar );
552}
553//*************************************************************************************************
554
555
556//*************************************************************************************************
571template< typename MT // Type of the left-hand side dense matrix
572 , bool SO // Storage order
573 , typename ST > // Data type of the right-hand side scalar
574inline auto operator/=( DenseMatrix<MT,SO>& mat, ST scalar )
576{
578
579 BLAZE_USER_ASSERT( isDivisor( scalar ), "Division by zero detected" );
580
581 if( IsRestricted_v<MT> ) {
582 if( !tryDiv( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
583 BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
584 }
585 }
586
587 decltype(auto) left( derestrict( *mat ) );
588
589 smpAssign( left, left / scalar );
590
591 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
592
593 return *mat;
594}
595//*************************************************************************************************
596
597
598//*************************************************************************************************
613template< typename MT // Type of the left-hand side dense matrix
614 , bool SO // Storage order
615 , typename ST > // Data type of the right-hand side scalar
616inline auto operator/=( DenseMatrix<MT,SO>&& mat, ST scalar )
618{
619 return operator/=( *mat, scalar );
620}
621//*************************************************************************************************
622
623
624//*************************************************************************************************
636template< typename MT // Type of the dense matrix
637 , bool SO > // Storage order
638inline MT& operator<<=( DenseMatrix<MT,SO>& mat, int count )
639{
641
642 if( IsRestricted_v<MT> ) {
643 if( !tryShift( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), count ) ) {
644 BLAZE_THROW_INVALID_ARGUMENT( "Invalid left-shift of restricted matrix" );
645 }
646 }
647
648 decltype(auto) left( derestrict( *mat ) );
649
650 smpAssign( left, left << count );
651
652 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
653
654 return *mat;
655}
656//*************************************************************************************************
657
658
659//*************************************************************************************************
671template< typename MT // Type of the dense matrix
672 , bool SO > // Storage order
673inline MT& operator<<=( DenseMatrix<MT,SO>&& mat, int count )
674{
675 return operator<<=( *mat, count );
676}
677//*************************************************************************************************
678
679
680//*************************************************************************************************
692template< typename MT1 // Type of the left-hand side dense matrix
693 , bool SO1 // Storage order of the left-hand side dense matrix
694 , typename MT2 // Type of the right-hand side dense matrix
695 , bool SO2 > // Storage order of the right-hand side dense matrix
697{
698 if( IsRestricted_v<MT1> ) {
699 if( !tryShiftAssign( *lhs, *rhs, 0UL, 0UL ) ) {
700 BLAZE_THROW_INVALID_ARGUMENT( "Invalid left-shift of restricted matrix" );
701 }
702 }
703
704 decltype(auto) left( derestrict( *lhs ) );
705
706 smpAssign( left, left << (*rhs) );
707
708 BLAZE_INTERNAL_ASSERT( isIntact( *lhs ), "Invariant violation detected" );
709
710 return *lhs;
711}
712//*************************************************************************************************
713
714
715//*************************************************************************************************
727template< typename MT1 // Type of the left-hand side dense matrix
728 , bool SO1 // Storage order of the left-hand side dense matrix
729 , typename MT2 // Type of the right-hand side dense matrix
730 , bool SO2 > // Storage order of the right-hand side dense matrix
732{
733 return operator<<=( *lhs, *rhs );
734}
735//*************************************************************************************************
736
737
738//*************************************************************************************************
750template< typename MT // Type of the dense matrix
751 , bool SO > // Storage order
752inline MT& operator>>=( DenseMatrix<MT,SO>& mat, int count )
753{
755
756 if( IsRestricted_v<MT> ) {
757 if( !tryShift( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), count ) ) {
758 BLAZE_THROW_INVALID_ARGUMENT( "Invalid right-shift of restricted matrix" );
759 }
760 }
761
762 decltype(auto) left( derestrict( *mat ) );
763
764 smpAssign( left, left >> count );
765
766 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
767
768 return *mat;
769}
770//*************************************************************************************************
771
772
773//*************************************************************************************************
785template< typename MT // Type of the dense matrix
786 , bool SO > // Storage order
787inline MT& operator>>=( DenseMatrix<MT,SO>&& mat, int count )
788{
789 return operator>>=( *mat, count );
790}
791//*************************************************************************************************
792
793
794//*************************************************************************************************
806template< typename MT1 // Type of the left-hand side dense matrix
807 , bool SO1 // Storage order of the left-hand side dense matrix
808 , typename MT2 // Type of the right-hand side dense matrix
809 , bool SO2 > // Storage order of the right-hand side dense matrix
811{
812 if( IsRestricted_v<MT1> ) {
813 if( !tryShiftAssign( *lhs, *rhs, 0UL, 0UL ) ) {
814 BLAZE_THROW_INVALID_ARGUMENT( "Invalid right-shift of restricted matrix" );
815 }
816 }
817
818 decltype(auto) left( derestrict( *lhs ) );
819
820 smpAssign( left, left >> (*rhs) );
821
822 BLAZE_INTERNAL_ASSERT( isIntact( *lhs ), "Invariant violation detected" );
823
824 return *lhs;
825}
826//*************************************************************************************************
827
828
829//*************************************************************************************************
841template< typename MT1 // Type of the left-hand side dense matrix
842 , bool SO1 // Storage order of the left-hand side dense matrix
843 , typename MT2 // Type of the right-hand side dense matrix
844 , bool SO2 > // Storage order of the right-hand side dense matrix
846{
847 return operator>>=( *lhs, *rhs );
848}
849//*************************************************************************************************
850
851
852//*************************************************************************************************
864template< typename MT // Type of the left-hand side dense matrix
865 , bool SO // Storage order
866 , typename ST > // Data type of the right-hand side scalar
867inline auto operator&=( DenseMatrix<MT,SO>& mat, ST scalar )
869{
871
872 if( IsRestricted_v<MT> ) {
873 if( !tryBitand( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
874 BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise AND of restricted matrix" );
875 }
876 }
877
878 decltype(auto) left( derestrict( *mat ) );
879
880 smpAssign( left, left & scalar );
881
882 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
883
884 return *mat;
885}
886//*************************************************************************************************
887
888
889//*************************************************************************************************
902template< typename MT // Type of the left-hand side dense matrix
903 , bool SO // Storage order
904 , typename ST > // Data type of the right-hand side scalar
905inline auto operator&=( DenseMatrix<MT,SO>&& mat, ST scalar )
907{
908 return operator&=( *mat, scalar );
909}
910//*************************************************************************************************
911
912
913//*************************************************************************************************
925template< typename MT1 // Type of the left-hand side dense matrix
926 , bool SO1 // Storage order of the left-hand side dense matrix
927 , typename MT2 // Type of the right-hand side dense matrix
928 , bool SO2 > // Storage order of the right-hand side dense matrix
930{
931 if( IsRestricted_v<MT1> ) {
932 if( !tryBitandAssign( *lhs, *rhs, 0UL, 0UL ) ) {
933 BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise AND of restricted matrix" );
934 }
935 }
936
937 decltype(auto) left( derestrict( *lhs ) );
938
939 smpAssign( left, left & (*rhs) );
940
941 BLAZE_INTERNAL_ASSERT( isIntact( *lhs ), "Invariant violation detected" );
942
943 return *lhs;
944}
945//*************************************************************************************************
946
947
948//*************************************************************************************************
960template< typename MT1 // Type of the left-hand side dense matrix
961 , bool SO1 // Storage order of the left-hand side dense matrix
962 , typename MT2 // Type of the right-hand side dense matrix
963 , bool SO2 > // Storage order of the right-hand side dense matrix
965{
966 return operator&=( *lhs, *rhs );
967}
968//*************************************************************************************************
969
970
971//*************************************************************************************************
983template< typename MT // Type of the left-hand side dense matrix
984 , bool SO // Storage order
985 , typename ST > // Data type of the right-hand side scalar
986inline auto operator|=( DenseMatrix<MT,SO>& mat, ST scalar )
988{
990
991 if( IsRestricted_v<MT> ) {
992 if( !tryBitor( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
993 BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise OR of restricted matrix" );
994 }
995 }
996
997 decltype(auto) left( derestrict( *mat ) );
998
999 smpAssign( left, left | scalar );
1000
1001 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
1002
1003 return *mat;
1004}
1005//*************************************************************************************************
1006
1007
1008//*************************************************************************************************
1021template< typename MT // Type of the left-hand side dense matrix
1022 , bool SO // Storage order
1023 , typename ST > // Data type of the right-hand side scalar
1024inline auto operator|=( DenseMatrix<MT,SO>&& mat, ST scalar )
1026{
1027 return operator|=( *mat, scalar );
1028}
1029//*************************************************************************************************
1030
1031
1032//*************************************************************************************************
1044template< typename MT1 // Type of the left-hand side dense matrix
1045 , bool SO1 // Storage order of the left-hand side dense matrix
1046 , typename MT2 // Type of the right-hand side dense matrix
1047 , bool SO2 > // Storage order of the right-hand side dense matrix
1049{
1050 if( IsRestricted_v<MT1> ) {
1051 if( !tryBitorAssign( *lhs, *rhs, 0UL, 0UL ) ) {
1052 BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise OR of restricted matrix" );
1053 }
1054 }
1055
1056 decltype(auto) left( derestrict( *lhs ) );
1057
1058 smpAssign( left, left | (*rhs) );
1059
1060 BLAZE_INTERNAL_ASSERT( isIntact( *lhs ), "Invariant violation detected" );
1061
1062 return *lhs;
1063}
1064//*************************************************************************************************
1065
1066
1067//*************************************************************************************************
1079template< typename MT1 // Type of the left-hand side dense matrix
1080 , bool SO1 // Storage order of the left-hand side dense matrix
1081 , typename MT2 // Type of the right-hand side dense matrix
1082 , bool SO2 > // Storage order of the right-hand side dense matrix
1084{
1085 return operator|=( *lhs, *rhs );
1086}
1087//*************************************************************************************************
1088
1089
1090//*************************************************************************************************
1102template< typename MT // Type of the left-hand side dense matrix
1103 , bool SO // Storage order
1104 , typename ST > // Data type of the right-hand side scalar
1105inline auto operator^=( DenseMatrix<MT,SO>& mat, ST scalar )
1107{
1109
1110 if( IsRestricted_v<MT> ) {
1111 if( !tryBitxor( *mat, 0UL, 0UL, (*mat).rows(), (*mat).columns(), scalar ) ) {
1112 BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise XOR of restricted matrix" );
1113 }
1114 }
1115
1116 decltype(auto) left( derestrict( *mat ) );
1117
1118 smpAssign( left, left ^ scalar );
1119
1120 BLAZE_INTERNAL_ASSERT( isIntact( *mat ), "Invariant violation detected" );
1121
1122 return *mat;
1123}
1124//*************************************************************************************************
1125
1126
1127//*************************************************************************************************
1140template< typename MT // Type of the left-hand side dense matrix
1141 , bool SO // Storage order
1142 , typename ST > // Data type of the right-hand side scalar
1143inline auto operator^=( DenseMatrix<MT,SO>&& mat, ST scalar )
1145{
1146 return operator^=( *mat, scalar );
1147}
1148//*************************************************************************************************
1149
1150
1151//*************************************************************************************************
1163template< typename MT1 // Type of the left-hand side dense matrix
1164 , bool SO1 // Storage order of the left-hand side dense matrix
1165 , typename MT2 // Type of the right-hand side dense matrix
1166 , bool SO2 > // Storage order of the right-hand side dense matrix
1168{
1169 if( IsRestricted_v<MT1> ) {
1170 if( !tryBitxorAssign( *lhs, *rhs, 0UL, 0UL ) ) {
1171 BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise XOR of restricted matrix" );
1172 }
1173 }
1174
1175 decltype(auto) left( derestrict( *lhs ) );
1176
1177 smpAssign( left, left ^ (*rhs) );
1178
1179 BLAZE_INTERNAL_ASSERT( isIntact( *lhs ), "Invariant violation detected" );
1180
1181 return *lhs;
1182}
1183//*************************************************************************************************
1184
1185
1186//*************************************************************************************************
1198template< typename MT1 // Type of the left-hand side dense matrix
1199 , bool SO1 // Storage order of the left-hand side dense matrix
1200 , typename MT2 // Type of the right-hand side dense matrix
1201 , bool SO2 > // Storage order of the right-hand side dense matrix
1203{
1204 return operator^=( *lhs, *rhs );
1205}
1206//*************************************************************************************************
1207
1208
1209
1210
1211//=================================================================================================
1212//
1213// GLOBAL FUNCTIONS
1214//
1215//=================================================================================================
1216
1217//*************************************************************************************************
1220template< typename MT, bool SO >
1221bool isnan( const DenseMatrix<MT,SO>& dm );
1222
1223template< typename MT, bool SO >
1224bool isinf( const DenseMatrix<MT,SO>& dm );
1225
1226template< typename MT, bool SO >
1227bool isfinite( const DenseMatrix<MT,SO>& dm );
1228
1229template< RelaxationFlag RF, typename MT, bool SO >
1230bool isSymmetric( const DenseMatrix<MT,SO>& dm );
1231
1232template< RelaxationFlag RF, typename MT, bool SO >
1233bool isHermitian( const DenseMatrix<MT,SO>& dm );
1234
1235template< RelaxationFlag RF, typename MT, bool SO >
1236bool isUniform( const DenseMatrix<MT,SO>& dm );
1237
1238template< RelaxationFlag RF, typename MT, bool SO >
1239bool isZero( const DenseMatrix<MT,SO>& dm );
1240
1241template< RelaxationFlag RF, typename MT, bool SO >
1242bool isLower( const DenseMatrix<MT,SO>& dm );
1243
1244template< RelaxationFlag RF, typename MT, bool SO >
1245bool isUniLower( const DenseMatrix<MT,SO>& dm );
1246
1247template< RelaxationFlag RF, typename MT, bool SO >
1248bool isStrictlyLower( const DenseMatrix<MT,SO>& dm );
1249
1250template< RelaxationFlag RF, typename MT, bool SO >
1251bool isUpper( const DenseMatrix<MT,SO>& dm );
1252
1253template< RelaxationFlag RF, typename MT, bool SO >
1254bool isUniUpper( const DenseMatrix<MT,SO>& dm );
1255
1256template< RelaxationFlag RF, typename MT, bool SO >
1257bool isStrictlyUpper( const DenseMatrix<MT,SO>& dm );
1258
1259template< RelaxationFlag RF, typename MT, bool SO >
1260bool isDiagonal( const DenseMatrix<MT,SO>& dm );
1261
1262template< RelaxationFlag RF, typename MT, bool SO >
1263bool isIdentity( const DenseMatrix<MT,SO>& dm );
1264
1265template< typename MT, bool SO >
1266bool isPositiveDefinite( const DenseMatrix<MT,SO>& dm );
1268//*************************************************************************************************
1269
1270
1271//*************************************************************************************************
1288template< typename MT // Type of the dense matrix
1289 , bool SO > // Storage order
1290bool isnan( const DenseMatrix<MT,SO>& dm )
1291{
1293 return false;
1294
1295 using CT = CompositeType_t<MT>;
1296
1297 CT A( *dm ); // Evaluation of the dense matrix operand
1298
1299 if( SO == rowMajor ) {
1300 for( size_t i=0UL; i<A.rows(); ++i ) {
1301 const size_t jbegin( IsUpper_v<MT> ? i : 0UL );
1302 const size_t jend ( IsLower_v<MT> ? i+1UL : A.columns() );
1303 for( size_t j=jbegin; j<jend; ++j )
1304 if( isnan( A(i,j) ) ) return true;
1305 }
1306 }
1307 else {
1308 for( size_t j=0UL; j<A.columns(); ++j ) {
1309 const size_t ibegin( IsLower_v<MT> ? j : 0UL );
1310 const size_t iend ( IsUpper_v<MT> ? j+1UL : A.rows() );
1311 for( size_t i=ibegin; i<iend; ++i )
1312 if( isnan( A(i,j) ) ) return true;
1313 }
1314 }
1315
1316 return false;
1317}
1318//*************************************************************************************************
1319
1320
1321//*************************************************************************************************
1337template< typename MT // Type of the dense matrix
1338 , bool SO > // Storage order
1339bool isinf( const DenseMatrix<MT,SO>& dm )
1340{
1342 return false;
1343
1344 using CT = CompositeType_t<MT>;
1345
1346 CT A( *dm ); // Evaluation of the dense matrix operand
1347
1348 if( SO == rowMajor ) {
1349 for( size_t i=0UL; i<A.rows(); ++i ) {
1350 const size_t jbegin( IsUpper_v<MT> ? i : 0UL );
1351 const size_t jend ( IsLower_v<MT> ? i+1UL : A.columns() );
1352 for( size_t j=jbegin; j<jend; ++j )
1353 if( isinf( A(i,j) ) ) return true;
1354 }
1355 }
1356 else {
1357 for( size_t j=0UL; j<A.columns(); ++j ) {
1358 const size_t ibegin( IsLower_v<MT> ? j : 0UL );
1359 const size_t iend ( IsUpper_v<MT> ? j+1UL : A.rows() );
1360 for( size_t i=ibegin; i<iend; ++i )
1361 if( isinf( A(i,j) ) ) return true;
1362 }
1363 }
1364
1365 return false;
1366}
1367//*************************************************************************************************
1368
1369
1370//*************************************************************************************************
1387template< typename MT // Type of the dense matrix
1388 , bool SO > // Storage order
1390{
1392 return true;
1393
1394 using CT = CompositeType_t<MT>;
1395
1396 CT A( *dm ); // Evaluation of the dense matrix operand
1397
1398 if( SO == rowMajor ) {
1399 for( size_t i=0UL; i<A.rows(); ++i ) {
1400 const size_t jbegin( IsUpper_v<MT> ? i : 0UL );
1401 const size_t jend ( IsLower_v<MT> ? i+1UL : A.columns() );
1402 for( size_t j=jbegin; j<jend; ++j )
1403 if( !isfinite( A(i,j) ) ) return false;
1404 }
1405 }
1406 else {
1407 for( size_t j=0UL; j<A.columns(); ++j ) {
1408 const size_t ibegin( IsLower_v<MT> ? j : 0UL );
1409 const size_t iend ( IsUpper_v<MT> ? j+1UL : A.rows() );
1410 for( size_t i=ibegin; i<iend; ++i )
1411 if( !isfinite( A(i,j) ) ) return false;
1412 }
1413 }
1414
1415 return true;
1416}
1417//*************************************************************************************************
1418
1419
1420//*************************************************************************************************
1453template< RelaxationFlag RF // Relaxation flag
1454 , typename MT // Type of the dense matrix
1455 , bool SO > // Storage order
1457{
1458 using CT = CompositeType_t<MT>;
1459
1460 if( IsSymmetric_v<MT> )
1461 return true;
1462
1463 if( !isSquare( *dm ) )
1464 return false;
1465
1466 if( IsUniform_v<MT> || (*dm).rows() < 2UL )
1467 return true;
1468
1469 if( IsTriangular_v<MT> )
1470 return isDiagonal( *dm );
1471
1472 CT A( *dm ); // Evaluation of the dense matrix operand
1473
1474 if( SO == rowMajor ) {
1475 for( size_t i=1UL; i<A.rows(); ++i ) {
1476 for( size_t j=0UL; j<i; ++j ) {
1477 if( !equal<RF>( A(i,j), A(j,i) ) )
1478 return false;
1479 }
1480 }
1481 }
1482 else {
1483 for( size_t j=1UL; j<A.columns(); ++j ) {
1484 for( size_t i=0UL; i<j; ++i ) {
1485 if( !equal<RF>( A(i,j), A(j,i) ) )
1486 return false;
1487 }
1488 }
1489 }
1490
1491 return true;
1492}
1493//*************************************************************************************************
1494
1495
1496//*************************************************************************************************
1531template< RelaxationFlag RF // Relaxation flag
1532 , typename MT // Type of the dense matrix
1533 , bool SO > // Storage order
1535{
1536 using ET = ElementType_t<MT>;
1537 using CT = CompositeType_t<MT>;
1538
1539 if( IsHermitian_v<MT> )
1540 return true;
1541
1542 if( !IsScalar_v<ET> || !isSquare( *dm ) )
1543 return false;
1544
1545 if( IsBuiltin_v<ET> && IsUniform_v<MT> )
1546 return true;
1547
1548 CT A( *dm ); // Evaluation of the dense matrix operand
1549
1550 if( SO == rowMajor ) {
1551 for( size_t i=0UL; i<A.rows(); ++i ) {
1552 for( size_t j=0UL; j<i; ++j ) {
1553 if( !equal<RF>( A(i,j), conj( A(j,i) ) ) )
1554 return false;
1555 }
1556 if( !isReal<RF>( A(i,i) ) )
1557 return false;
1558 }
1559 }
1560 else {
1561 for( size_t j=0UL; j<A.columns(); ++j ) {
1562 for( size_t i=0UL; i<j; ++i ) {
1563 if( !equal<RF>( A(i,j), conj( A(j,i) ) ) )
1564 return false;
1565 }
1566 if( !isReal<RF>( A(j,j) ) )
1567 return false;
1568 }
1569 }
1570
1571 return true;
1572}
1573//*************************************************************************************************
1574
1575
1576//*************************************************************************************************
1584template< RelaxationFlag RF // Relaxation flag
1585 , typename MT > // Type of the dense matrix
1586bool isUniform_backend( const DenseMatrix<MT,false>& dm, TrueType )
1587{
1590
1591 BLAZE_INTERNAL_ASSERT( (*dm).rows() != 0UL, "Invalid number of rows detected" );
1592 BLAZE_INTERNAL_ASSERT( (*dm).columns() != 0UL, "Invalid number of columns detected" );
1593
1594 const size_t ibegin( ( IsStrictlyLower_v<MT> )?( 1UL ):( 0UL ) );
1595 const size_t iend ( ( IsStrictlyUpper_v<MT> )?( (*dm).rows()-1UL ):( (*dm).rows() ) );
1596
1597 for( size_t i=ibegin; i<iend; ++i ) {
1598 if( !IsUpper_v<MT> ) {
1599 for( size_t j=0UL; j<i; ++j ) {
1600 if( !isDefault<RF>( (*dm)(i,j) ) )
1601 return false;
1602 }
1603 }
1604 if( !isDefault<RF>( (*dm)(i,i) ) )
1605 return false;
1606 if( !IsLower_v<MT> ) {
1607 for( size_t j=i+1UL; j<(*dm).columns(); ++j ) {
1608 if( !isDefault<RF>( (*dm)(i,j) ) )
1609 return false;
1610 }
1611 }
1612 }
1613
1614 return true;
1615}
1617//*************************************************************************************************
1618
1619
1620//*************************************************************************************************
1628template< RelaxationFlag RF // Relaxation flag
1629 , typename MT > // Type of the dense matrix
1630bool isUniform_backend( const DenseMatrix<MT,true>& dm, TrueType )
1631{
1634
1635 BLAZE_INTERNAL_ASSERT( (*dm).rows() != 0UL, "Invalid number of rows detected" );
1636 BLAZE_INTERNAL_ASSERT( (*dm).columns() != 0UL, "Invalid number of columns detected" );
1637
1638 const size_t jbegin( ( IsStrictlyUpper_v<MT> )?( 1UL ):( 0UL ) );
1639 const size_t jend ( ( IsStrictlyLower_v<MT> )?( (*dm).columns()-1UL ):( (*dm).columns() ) );
1640
1641 for( size_t j=jbegin; j<jend; ++j ) {
1642 if( !IsLower_v<MT> ) {
1643 for( size_t i=0UL; i<j; ++i ) {
1644 if( !isDefault<RF>( (*dm)(i,j) ) )
1645 return false;
1646 }
1647 }
1648 if( !isDefault<RF>( (*dm)(j,j) ) )
1649 return false;
1650 if( !IsUpper_v<MT> ) {
1651 for( size_t i=j+1UL; i<(*dm).rows(); ++i ) {
1652 if( !isDefault<RF>( (*dm)(i,j) ) )
1653 return false;
1654 }
1655 }
1656 }
1657
1658 return true;
1659}
1661//*************************************************************************************************
1662
1663
1664//*************************************************************************************************
1672template< RelaxationFlag RF // Relaxation flag
1673 , typename MT > // Type of the dense matrix
1674bool isUniform_backend( const DenseMatrix<MT,false>& dm, FalseType )
1675{
1678
1679 BLAZE_INTERNAL_ASSERT( (*dm).rows() != 0UL, "Invalid number of rows detected" );
1680 BLAZE_INTERNAL_ASSERT( (*dm).columns() != 0UL, "Invalid number of columns detected" );
1681
1682 const auto& cmp( (*dm)(0UL,0UL) );
1683
1684 for( size_t i=0UL; i<(*dm).rows(); ++i ) {
1685 for( size_t j=0UL; j<(*dm).columns(); ++j ) {
1686 if( !equal<RF>( (*dm)(i,j), cmp ) )
1687 return false;
1688 }
1689 }
1690
1691 return true;
1692}
1694//*************************************************************************************************
1695
1696
1697//*************************************************************************************************
1705template< RelaxationFlag RF // Relaxation flag
1706 , typename MT > // Type of the dense matrix
1707bool isUniform_backend( const DenseMatrix<MT,true>& dm, FalseType )
1708{
1711
1712 BLAZE_INTERNAL_ASSERT( (*dm).rows() != 0UL, "Invalid number of rows detected" );
1713 BLAZE_INTERNAL_ASSERT( (*dm).columns() != 0UL, "Invalid number of columns detected" );
1714
1715 const auto& cmp( (*dm)(0UL,0UL) );
1716
1717 for( size_t j=0UL; j<(*dm).columns(); ++j ) {
1718 for( size_t i=0UL; i<(*dm).rows(); ++i ) {
1719 if( !equal<RF>( (*dm)(i,j), cmp ) )
1720 return false;
1721 }
1722 }
1723
1724 return true;
1725}
1727//*************************************************************************************************
1728
1729
1730//*************************************************************************************************
1763template< RelaxationFlag RF // Relaxation flag
1764 , typename MT // Type of the dense matrix
1765 , bool SO > // Storage order
1767{
1768 if( IsUniform_v<MT> ||
1769 (*dm).rows() == 0UL || (*dm).columns() == 0UL ||
1770 ( (*dm).rows() == 1UL && (*dm).columns() == 1UL ) )
1771 return true;
1772
1773 if( IsUniTriangular_v<MT> )
1774 return false;
1775
1776 CompositeType_t<MT> A( *dm ); // Evaluation of the dense matrix operand
1777
1778 return isUniform_backend<RF>( A, typename IsTriangular<MT>::Type() );
1779}
1780//*************************************************************************************************
1781
1782
1783//*************************************************************************************************
1816template< RelaxationFlag RF // Relaxation flag
1817 , typename MT // Type of the dense matrix
1818 , bool SO > // Storage order
1820{
1821 const size_t M( (*dm).rows() );
1822 const size_t N( (*dm).columns() );
1823
1824 if( IsZero_v<MT> || M == 0UL || N == 0UL )
1825 return true;
1826
1827 if( IsUniTriangular_v<MT> )
1828 return false;
1829
1830 if( IsUniform_v<MT> )
1831 return isZero<RF>( (*dm)(0UL,0UL) );
1832
1833 CompositeType_t<MT> A( *dm ); // Evaluation of the dense matrix operand
1834
1835 if( SO == rowMajor )
1836 {
1837 for( size_t i=0UL; i<M; ++i )
1838 {
1839 const size_t jbegin( IsUpper_v<MT>
1840 ? ( IsStrictlyUpper_v<MT> ? i+1UL : i )
1841 : 0UL );
1842 const size_t jend ( IsLower_v<MT> || IsSymmetric_v<MT> || IsHermitian_v<MT>
1843 ? ( IsStrictlyLower_v<MT> ? i : i+1UL )
1844 : N );
1845
1846 for( size_t j=jbegin; j<jend; ++j ) {
1847 if( !isZero<RF>( A(i,j) ) )
1848 return false;
1849 }
1850 }
1851 }
1852 else
1853 {
1854 for( size_t j=0UL; j<N; ++j )
1855 {
1856 const size_t ibegin( IsLower_v<MT>
1857 ? ( IsStrictlyLower_v<MT> ? j+1UL : j )
1858 : 0UL );
1859 const size_t iend ( IsUpper_v<MT> || IsSymmetric_v<MT> || IsHermitian_v<MT>
1860 ? ( IsStrictlyUpper_v<MT> ? j : j+1UL )
1861 : M );
1862
1863 for( size_t i=ibegin; i<iend; ++i ) {
1864 if( !isZero<RF>( A(i,j) ) )
1865 return false;
1866 }
1867 }
1868 }
1869
1870 return true;
1871}
1872//*************************************************************************************************
1873
1874
1875//*************************************************************************************************
1918template< RelaxationFlag RF // Relaxation flag
1919 , typename MT // Type of the dense matrix
1920 , bool SO > // Storage order
1922{
1923 using RT = ResultType_t<MT>;
1924 using RN = ReturnType_t<MT>;
1925 using CT = CompositeType_t<MT>;
1926 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1927
1928 if( IsLower_v<MT> )
1929 return true;
1930
1931 if( !isSquare( *dm ) )
1932 return false;
1933
1934 if( IsZero_v<MT> || (*dm).rows() < 2UL )
1935 return true;
1936
1937 Tmp A( *dm ); // Evaluation of the dense matrix operand
1938
1939 if( IsUniform_v<MT> )
1940 return isDefault<RF>( A(0UL,0UL) );
1941
1942 if( SO == rowMajor ) {
1943 for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
1944 for( size_t j=i+1UL; j<A.columns(); ++j ) {
1945 if( !isDefault<RF>( A(i,j) ) )
1946 return false;
1947 }
1948 }
1949 }
1950 else {
1951 for( size_t j=1UL; j<A.columns(); ++j ) {
1952 for( size_t i=0UL; i<j; ++i ) {
1953 if( !isDefault<RF>( A(i,j) ) )
1954 return false;
1955 }
1956 }
1957 }
1958
1959 return true;
1960}
1961//*************************************************************************************************
1962
1963
1964//*************************************************************************************************
2006template< RelaxationFlag RF // Relaxation flag
2007 , typename MT // Type of the dense matrix
2008 , bool SO > // Storage order
2010{
2011 using RT = ResultType_t<MT>;
2012 using RN = ReturnType_t<MT>;
2013 using CT = CompositeType_t<MT>;
2014 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2015
2016 if( IsUniLower_v<MT> )
2017 return true;
2018
2019 if( !isSquare( *dm ) )
2020 return false;
2021
2022 Tmp A( *dm ); // Evaluation of the dense matrix operand
2023
2024 if( SO == rowMajor ) {
2025 for( size_t i=0UL; i<A.rows(); ++i ) {
2026 if( !isOne<RF>( A(i,i) ) )
2027 return false;
2028 for( size_t j=i+1UL; j<A.columns(); ++j ) {
2029 if( !isZero<RF>( A(i,j) ) )
2030 return false;
2031 }
2032 }
2033 }
2034 else {
2035 for( size_t j=0UL; j<A.columns(); ++j ) {
2036 for( size_t i=0UL; i<j; ++i ) {
2037 if( !isZero<RF>( A(i,j) ) )
2038 return false;
2039 }
2040 if( !isOne<RF>( A(j,j) ) )
2041 return false;
2042 }
2043 }
2044
2045 return true;
2046}
2047//*************************************************************************************************
2048
2049
2050//*************************************************************************************************
2093template< RelaxationFlag RF // Relaxation flag
2094 , typename MT // Type of the dense matrix
2095 , bool SO > // Storage order
2097{
2098 using RT = ResultType_t<MT>;
2099 using RN = ReturnType_t<MT>;
2100 using CT = CompositeType_t<MT>;
2101 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2102
2103 if( IsStrictlyLower_v<MT> )
2104 return true;
2105
2106 if( !isSquare( *dm ) )
2107 return false;
2108
2109 if( IsZero_v<MT> || (*dm).rows() < 2UL )
2110 return true;
2111
2112 if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
2113 return false;
2114
2115 Tmp A( *dm ); // Evaluation of the dense matrix operand
2116
2117 if( IsUniform_v<MT> )
2118 return isDefault<RF>( A(0UL,0UL) );
2119
2120 if( SO == rowMajor ) {
2121 for( size_t i=0UL; i<A.rows(); ++i ) {
2122 for( size_t j=i; j<A.columns(); ++j ) {
2123 if( !isDefault<RF>( A(i,j) ) )
2124 return false;
2125 }
2126 }
2127 }
2128 else {
2129 for( size_t j=0UL; j<A.columns(); ++j ) {
2130 for( size_t i=0UL; i<=j; ++i ) {
2131 if( !isDefault<RF>( A(i,j) ) )
2132 return false;
2133 }
2134 }
2135 }
2136
2137 return true;
2138}
2139//*************************************************************************************************
2140
2141
2142//*************************************************************************************************
2185template< RelaxationFlag RF // Relaxation flag
2186 , typename MT // Type of the dense matrix
2187 , bool SO > // Storage order
2189{
2190 using RT = ResultType_t<MT>;
2191 using RN = ReturnType_t<MT>;
2192 using CT = CompositeType_t<MT>;
2193 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2194
2195 if( IsUpper_v<MT> )
2196 return true;
2197
2198 if( !isSquare( *dm ) )
2199 return false;
2200
2201 if( IsZero_v<MT> || (*dm).rows() < 2UL )
2202 return true;
2203
2204 Tmp A( *dm ); // Evaluation of the dense matrix operand
2205
2206 if( IsUniform_v<MT> )
2207 return isDefault<RF>( A(0UL,0UL) );
2208
2209 if( SO == rowMajor ) {
2210 for( size_t i=1UL; i<A.rows(); ++i ) {
2211 for( size_t j=0UL; j<i; ++j ) {
2212 if( !isDefault<RF>( A(i,j) ) )
2213 return false;
2214 }
2215 }
2216 }
2217 else {
2218 for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
2219 for( size_t i=j+1UL; i<A.rows(); ++i ) {
2220 if( !isDefault<RF>( A(i,j) ) )
2221 return false;
2222 }
2223 }
2224 }
2225
2226 return true;
2227}
2228//*************************************************************************************************
2229
2230
2231//*************************************************************************************************
2273template< RelaxationFlag RF // Relaxation flag
2274 , typename MT // Type of the dense matrix
2275 , bool SO > // Storage order
2277{
2278 using RT = ResultType_t<MT>;
2279 using RN = ReturnType_t<MT>;
2280 using CT = CompositeType_t<MT>;
2281 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2282
2283 if( IsUniUpper_v<MT> )
2284 return true;
2285
2286 if( !isSquare( *dm ) )
2287 return false;
2288
2289 Tmp A( *dm ); // Evaluation of the dense matrix operand
2290
2291 if( SO == rowMajor ) {
2292 for( size_t i=0UL; i<A.rows(); ++i ) {
2293 for( size_t j=0UL; j<i; ++j ) {
2294 if( !isZero<RF>( A(i,j) ) )
2295 return false;
2296 }
2297 if( !isOne<RF>( A(i,i) ) )
2298 return false;
2299 }
2300 }
2301 else {
2302 for( size_t j=0UL; j<A.columns(); ++j ) {
2303 if( !isOne<RF>( A(j,j) ) )
2304 return false;
2305 for( size_t i=j+1UL; i<A.rows(); ++i ) {
2306 if( !isZero<RF>( A(i,j) ) )
2307 return false;
2308 }
2309 }
2310 }
2311
2312 return true;
2313}
2314//*************************************************************************************************
2315
2316
2317//*************************************************************************************************
2360template< RelaxationFlag RF // Relaxation flag
2361 , typename MT // Type of the dense matrix
2362 , bool SO > // Storage order
2364{
2365 using RT = ResultType_t<MT>;
2366 using RN = ReturnType_t<MT>;
2367 using CT = CompositeType_t<MT>;
2368 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2369
2370 if( IsStrictlyUpper_v<MT> )
2371 return true;
2372
2373 if( !isSquare( *dm ) )
2374 return false;
2375
2376 if( IsZero_v<MT> || (*dm).rows() < 2UL )
2377 return true;
2378
2379 if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
2380 return false;
2381
2382 Tmp A( *dm ); // Evaluation of the dense matrix operand
2383
2384 if( IsUniform_v<MT> )
2385 return isDefault<RF>( A(0UL,0UL) );
2386
2387 if( SO == rowMajor ) {
2388 for( size_t i=0UL; i<A.rows(); ++i ) {
2389 for( size_t j=0UL; j<=i; ++j ) {
2390 if( !isDefault<RF>( A(i,j) ) )
2391 return false;
2392 }
2393 }
2394 }
2395 else {
2396 for( size_t j=0UL; j<A.columns(); ++j ) {
2397 for( size_t i=j; i<A.rows(); ++i ) {
2398 if( !isDefault<RF>( A(i,j) ) )
2399 return false;
2400 }
2401 }
2402 }
2403
2404 return true;
2405}
2406//*************************************************************************************************
2407
2408
2409//*************************************************************************************************
2453template< RelaxationFlag RF // Relaxation flag
2454 , typename MT // Type of the dense matrix
2455 , bool SO > // Storage order
2457{
2458 using RT = ResultType_t<MT>;
2459 using RN = ReturnType_t<MT>;
2460 using CT = CompositeType_t<MT>;
2461 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2462
2463 if( IsDiagonal_v<MT> )
2464 return true;
2465
2466 if( !isSquare( *dm ) )
2467 return false;
2468
2469 if( IsZero_v<MT> || (*dm).rows() < 2UL )
2470 return true;
2471
2472 Tmp A( *dm ); // Evaluation of the dense matrix operand
2473
2474 if( IsUniform_v<MT> )
2475 return isDefault<RF>( A(0UL,0UL) );
2476
2477 if( SO == rowMajor ) {
2478 for( size_t i=0UL; i<A.rows(); ++i ) {
2479 if( !IsUpper_v<MT> ) {
2480 for( size_t j=0UL; j<i; ++j ) {
2481 if( !isDefault<RF>( A(i,j) ) )
2482 return false;
2483 }
2484 }
2485 if( !IsLower_v<MT> ) {
2486 for( size_t j=i+1UL; j<A.columns(); ++j ) {
2487 if( !isDefault<RF>( A(i,j) ) )
2488 return false;
2489 }
2490 }
2491 }
2492 }
2493 else {
2494 for( size_t j=0UL; j<A.columns(); ++j ) {
2495 if( !IsLower_v<MT> ) {
2496 for( size_t i=0UL; i<j; ++i ) {
2497 if( !isDefault<RF>( A(i,j) ) )
2498 return false;
2499 }
2500 }
2501 if( !IsUpper_v<MT> ) {
2502 for( size_t i=j+1UL; i<A.rows(); ++i ) {
2503 if( !isDefault<RF>( A(i,j) ) )
2504 return false;
2505 }
2506 }
2507 }
2508 }
2509
2510 return true;
2511}
2512//*************************************************************************************************
2513
2514
2515//*************************************************************************************************
2558template< RelaxationFlag RF // Relaxation flag
2559 , typename MT // Type of the dense matrix
2560 , bool SO > // Storage order
2562{
2563 using RT = ResultType_t<MT>;
2564 using RN = ReturnType_t<MT>;
2565 using CT = CompositeType_t<MT>;
2566 using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2567
2568 if( IsIdentity_v<MT> )
2569 return true;
2570
2571 if( !isSquare( *dm ) )
2572 return false;
2573
2574 if( (*dm).rows() == 0UL )
2575 return true;
2576
2577 Tmp A( *dm ); // Evaluation of the dense matrix operand
2578
2579 if( SO == rowMajor ) {
2580 for( size_t i=0UL; i<A.rows(); ++i ) {
2581 if( !IsUpper_v<MT> ) {
2582 for( size_t j=0UL; j<i; ++j ) {
2583 if( !isZero<RF>( A(i,j) ) )
2584 return false;
2585 }
2586 }
2587 if( !IsUniLower_v<MT> && !IsUniUpper_v<MT> && !isOne<RF>( A(i,i) ) ) {
2588 return false;
2589 }
2590 if( !IsLower_v<MT> ) {
2591 for( size_t j=i+1UL; j<A.columns(); ++j ) {
2592 if( !isZero<RF>( A(i,j) ) )
2593 return false;
2594 }
2595 }
2596 }
2597 }
2598 else {
2599 for( size_t j=0UL; j<A.columns(); ++j ) {
2600 if( !IsLower_v<MT> ) {
2601 for( size_t i=0UL; i<j; ++i ) {
2602 if( !isZero<RF>( A(i,j) ) )
2603 return false;
2604 }
2605 }
2606 if( !IsUniLower_v<MT> && !IsUniUpper_v<MT> && !isOne<RF>( A(j,j) ) ) {
2607 return false;
2608 }
2609 if( !IsUpper_v<MT> ) {
2610 for( size_t i=j+1UL; i<A.rows(); ++i ) {
2611 if( !isZero<RF>( A(i,j) ) )
2612 return false;
2613 }
2614 }
2615 }
2616 }
2617
2618 return true;
2619}
2620//*************************************************************************************************
2621
2622
2623//*************************************************************************************************
2655template< typename MT // Type of the dense matrix
2656 , bool SO > // Storage order
2658{
2660
2661 if( !isSquare( *dm ) )
2662 return false;
2663
2664 if( (*dm).rows() < 2UL )
2665 return true;
2666
2668
2669 char uplo( IsRowMajorMatrix_v<MT> ? 'U' : 'L' );
2670 blas_int_t n ( numeric_cast<blas_int_t>( (*L).rows() ) );
2671 blas_int_t lda ( numeric_cast<blas_int_t>( (*L).spacing()) );
2672 blas_int_t info( 0 );
2673
2674 potrf( uplo, n, (*L).data(), lda, &info );
2675
2676 return ( info == 0 );
2677}
2678//*************************************************************************************************
2679
2680
2681//*************************************************************************************************
2713template< typename MT // Type of the dense matrix
2714 , bool SO > // Storage order
2715size_t rank( const DenseMatrix<MT,SO>& dm )
2716{
2719
2720 using BT = UnderlyingBuiltin_t<MT>;
2721
2722 const auto s( evaluate( svd( *dm ) ) );
2723
2724 const BT tolerance( max( rows(dm), columns(dm) ) * Limits<BT>::epsilon() * max(s) );
2725 return std::count_if( begin(s), end(s), [tolerance]( auto val ) { return abs(val) > tolerance; } );
2726}
2727//*************************************************************************************************
2728
2729} // namespace blaze
2730
2731#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.
Constraint on the data type.
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the conjugate shim.
Header file for the EnableIf class template.
Numerical epsilon value for floating point data types.
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 isDefault shim.
Header file for the IsDiagonal type trait.
Header file for the isDivisor shim.
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 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 IsRestricted type trait.
Header file for the IsRowMajorMatrix type trait.
Header file for the IsScalar 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.
Numerical limits of built-in data types.
Cast operators for numeric types.
Header file for the reduction flags.
Header file for the relaxation flag enumeration.
Header file for the RemoveAdaptor type trait.
Constraint on the data type.
Header file for the UnderlyingBuiltin type trait.
Constraint on the data type.
Header file for the CLAPACK potrf wrapper functions.
Base class for dense matrices.
Definition: DenseMatrix.h:82
Constraint on the data type.
Constraint on the data type.
Header file for the DenseMatrix base class.
auto operator+=(DenseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a temporary dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:424
auto operator*=(DenseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a temporary dense matrix and a scalar va...
Definition: DenseMatrix.h:548
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:2096
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1375
auto operator!=(T1 scalar, const DenseMatrix< T2, SO > &mat) -> EnableIf_t< IsScalar_v< T2 >, bool >
Inequality operator for the comparison of a scalar value and a dense matrix.
Definition: DenseMatrix.h:362
bool isinf(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for infinite elements.
Definition: DenseMatrix.h:1339
auto operator-=(DenseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a temporary dense matrix and a scalar value ( ...
Definition: DenseMatrix.h:486
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
MT1 & operator<<=(DenseMatrix< MT1, SO1 > &&lhs, const DenseMatrix< MT2, SO2 > &rhs)
Left-shift assignment operator for the elementwise left-shift of a temporary dense matrix.
Definition: DenseMatrix.h:731
MT1 & operator>>=(DenseMatrix< MT1, SO1 > &&lhs, const DenseMatrix< MT2, SO2 > &rhs)
Right-shift assignment operator for the elementwise right-shift of a temporary dense.
Definition: DenseMatrix.h:845
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1921
MT1 & operator|=(DenseMatrix< MT1, SO1 > &&lhs, const DenseMatrix< MT2, SO2 > &rhs)
Bitwise OR assignment operator for the bitwise OR of a temporary dense matrix.
Definition: DenseMatrix.h:1083
bool isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:1766
decltype(auto) abs(const DenseMatrix< MT, SO > &dm)
Applies the abs() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1296
bool isPositiveDefinite(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a positive definite matrix.
Definition: DenseMatrix.h:2657
bool isnan(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for not-a-number elements.
Definition: DenseMatrix.h:1290
void svd(const DenseMatrix< MT, SO > &A, DenseVector< VT, TF > &s)
Singular value decomposition (SVD) of the given dense general matrix.
Definition: SVD.h:135
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:2009
auto operator/=(DenseMatrix< MT, SO > &&mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a temporary dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:616
size_t rank(const DenseMatrix< MT, SO > &dm)
Computes the rank of the given dense matrix.
Definition: DenseMatrix.h:2715
bool isfinite(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for finite elements.
Definition: DenseMatrix.h:1389
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:2363
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:1534
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:1456
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:2276
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is diagonal.
Definition: DenseMatrix.h:2456
bool isZero(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a zero matrix.
Definition: DenseMatrix.h:1819
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:2188
MT1 & operator&=(DenseMatrix< MT1, SO1 > &&lhs, const DenseMatrix< MT2, SO2 > &rhs)
Bitwise AND assignment operator for the bitwise AND of a temporary dense matrix.
Definition: DenseMatrix.h:964
bool isIdentity(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an identity matrix.
Definition: DenseMatrix.h:2561
auto operator==(T1 scalar, const DenseMatrix< T2, SO > &mat) -> EnableIf_t< IsScalar_v< T2 >, bool >
Equality operator for the comparison of a scalar value and a dense matrix.
Definition: DenseMatrix.h:316
MT1 & operator^=(DenseMatrix< MT1, SO1 > &&lhs, const DenseMatrix< MT2, SO2 > &rhs)
Bitwise XOR assignment operator for the bitwise XOR of a temporary dense matrix.
Definition: DenseMatrix.h:1202
bool isDivisor(const DenseVector< VT, TF > &dv)
Returns whether the given dense vector is a valid divisor.
Definition: DenseVector.h:1261
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
void potrf(char uplo, blas_int_t n, float *A, blas_int_t lda, blas_int_t *info)
LAPACK kernel for the Cholesky decomposition of the given dense positive definite single precision co...
Definition: potrf.h:137
#define BLAZE_CONSTRAINT_MUST_BE_BLAS_COMPATIBLE_TYPE(T)
Constraint on the data type.
Definition: BLASCompatible.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.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 UnderlyingBuiltin< T >::Type UnderlyingBuiltin_t
Auxiliary alias declaration for the UnderlyingBuiltin type trait.
Definition: UnderlyingBuiltin.h:117
typename RemoveAdaptor< T >::Type RemoveAdaptor_t
Auxiliary alias declaration for the RemoveAdaptor type trait.
Definition: RemoveAdaptor.h:153
RelaxationFlag
Relaxation flag for strict or relaxed semantics.
Definition: RelaxationFlag.h:66
int32_t blas_int_t
Signed integer type used in the BLAS/LAPACK wrapper functions.
Definition: Types.h:64
MT::ResultType evaluate(const Matrix< MT, SO > &matrix)
Evaluates the given matrix expression.
Definition: Matrix.h:1282
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
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:584
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
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
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:343
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
Numerical limits of built-in data types.
Definition: Limits.h:108
Header file for the IsZero type trait.
Header file for basic type definitions.
Header file for the generic max algorithm.