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 <blaze/math/Aliases.h>
50 #include <blaze/math/shims/Equal.h>
52 #include <blaze/math/shims/IsNaN.h>
53 #include <blaze/math/shims/IsOne.h>
73 #include <blaze/math/views/Check.h>
74 #include <blaze/util/Assert.h>
76 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/FalseType.h>
78 #include <blaze/util/mpl/If.h>
79 #include <blaze/util/TrueType.h>
80 #include <blaze/util/Types.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // GLOBAL OPERATORS
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
96 template< typename T1, typename T2 >
97 auto operator==( const DenseMatrix<T1,false>& mat, T2 scalar )
98  -> EnableIf_t< IsNumeric_v<T2>, bool >;
99 
100 template< typename T1, typename T2 >
101 auto operator==( const DenseMatrix<T1,true>& mat, T2 scalar )
102  -> EnableIf_t< IsNumeric_v<T2>, bool >;
103 
104 template< typename T1, typename T2, bool SO >
105 auto operator==( T1 scalar, const DenseMatrix<T2,SO>& mat )
106  -> EnableIf_t< IsNumeric_v<T2>, bool >;
107 
108 template< typename T1, typename T2, bool SO >
109 auto operator!=( const DenseMatrix<T1,SO>& mat, T2 scalar )
110  -> EnableIf_t< IsNumeric_v<T2>, bool >;
111 
112 template< typename T1, typename T2, bool SO >
113 auto operator!=( T1 scalar, const DenseMatrix<T2,SO>& mat )
114  -> EnableIf_t< IsNumeric_v<T2>, bool >;
115 
116 template< typename MT, bool SO, typename ST >
117 auto operator*=( DenseMatrix<MT,SO>& mat, ST scalar )
118  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
119 
120 template< typename MT, bool SO, typename ST >
121 auto operator*=( DenseMatrix<MT,SO>&& mat, ST scalar )
122  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
123 
124 template< typename MT, bool SO, typename ST >
125 auto operator/=( DenseMatrix<MT,SO>& mat, ST scalar )
126  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
127 
128 template< typename MT, bool SO, typename ST >
129 auto operator/=( DenseMatrix<MT,SO>&& mat, ST scalar )
130  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
132 //*************************************************************************************************
133 
134 
135 //*************************************************************************************************
147 template< typename T1 // Type of the left-hand side dense matrix
148  , typename T2 > // Type of the right-hand side scalar
149 inline auto operator==( const DenseMatrix<T1,false>& mat, T2 scalar )
150  -> EnableIf_t< IsNumeric_v<T2>, bool >
151 {
152  using CT1 = CompositeType_t<T1>;
153 
154  // Evaluation of the dense matrix operand
155  CT1 A( ~mat );
156 
157  // In order to compare the matrix and the scalar value, the data values of the lower-order
158  // data type are converted to the higher-order data type within the equal function.
159  for( size_t i=0; i<A.rows(); ++i ) {
160  for( size_t j=0; j<A.columns(); ++j ) {
161  if( !equal( A(i,j), scalar ) ) return false;
162  }
163  }
164 
165  return true;
166 }
167 //*************************************************************************************************
168 
169 
170 //*************************************************************************************************
182 template< typename T1 // Type of the left-hand side dense matrix
183  , typename T2 > // Type of the right-hand side scalar
184 inline auto operator==( const DenseMatrix<T1,true>& mat, T2 scalar )
185  -> EnableIf_t< IsNumeric_v<T2>, bool >
186 {
187  using CT1 = CompositeType_t<T1>;
188 
189  // Evaluation of the dense matrix operand
190  CT1 A( ~mat );
191 
192  // In order to compare the matrix and the scalar value, the data values of the lower-order
193  // data type are converted to the higher-order data type within the equal function.
194  for( size_t j=0; j<A.columns(); ++j ) {
195  for( size_t i=0; i<A.rows(); ++i ) {
196  if( !equal( A(i,j), scalar ) ) return false;
197  }
198  }
199 
200  return true;
201 }
202 //*************************************************************************************************
203 
204 
205 //*************************************************************************************************
217 template< typename T1 // Type of the left-hand side scalar
218  , typename T2 // Type of the right-hand side dense matrix
219  , bool SO > // Storage order
220 inline auto operator==( T1 scalar, const DenseMatrix<T2,SO>& mat )
221  -> EnableIf_t< IsNumeric_v<T1>, bool >
222 {
223  return ( mat == scalar );
224 }
225 //*************************************************************************************************
226 
227 
228 //*************************************************************************************************
240 template< typename T1 // Type of the left-hand side dense matrix
241  , typename T2 // Type of the right-hand side scalar
242  , bool SO > // Storage order
243 inline auto operator!=( const DenseMatrix<T1,SO>& mat, T2 scalar )
244  -> EnableIf_t< IsNumeric_v<T2>, bool >
245 {
246  return !( mat == scalar );
247 }
248 //*************************************************************************************************
249 
250 
251 //*************************************************************************************************
263 template< typename T1 // Type of the left-hand side scalar
264  , typename T2 // Type of the right-hand side dense matrix
265  , bool SO > // Storage order
266 inline auto operator!=( T1 scalar, const DenseMatrix<T2,SO>& mat )
267  -> EnableIf_t< IsNumeric_v<T1>, bool >
268 {
269  return !( mat == scalar );
270 }
271 //*************************************************************************************************
272 
273 
274 //*************************************************************************************************
287 template< typename MT // Type of the left-hand side dense matrix
288  , bool SO // Storage order
289  , typename ST > // Data type of the right-hand side scalar
290 inline auto operator*=( DenseMatrix<MT,SO>& mat, ST scalar )
292 {
294 
295  if( IsRestricted_v<MT> ) {
296  if( !tryMult( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
297  BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
298  }
299  }
300 
301  BLAZE_DECLTYPE_AUTO( left, derestrict( ~mat ) );
302 
303  smpAssign( left, left * scalar );
304 
305  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
306 
307  return ~mat;
308 }
309 //*************************************************************************************************
310 
311 
312 //*************************************************************************************************
325 template< typename MT // Type of the left-hand side dense matrix
326  , bool SO // Storage order
327  , typename ST > // Data type of the right-hand side scalar
328 inline auto operator*=( DenseMatrix<MT,SO>&& mat, ST scalar )
330 {
331  return operator*=( ~mat, scalar );
332 }
333 //*************************************************************************************************
334 
335 
336 //*************************************************************************************************
351 template< typename MT // Type of the left-hand side dense matrix
352  , bool SO // Storage order
353  , typename ST > // Data type of the right-hand side scalar
354 inline auto operator/=( DenseMatrix<MT,SO>& mat, ST scalar )
356 {
358 
359  BLAZE_USER_ASSERT( !isZero( scalar ), "Division by zero detected" );
360 
361  if( IsRestricted_v<MT> ) {
362  if( !tryDiv( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
363  BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
364  }
365  }
366 
367  BLAZE_DECLTYPE_AUTO( left, derestrict( ~mat ) );
368 
369  smpAssign( left, left / scalar );
370 
371  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
372 
373  return ~mat;
374 }
375 //*************************************************************************************************
376 
377 
378 //*************************************************************************************************
393 template< typename MT // Type of the left-hand side dense matrix
394  , bool SO // Storage order
395  , typename ST > // Data type of the right-hand side scalar
396 inline auto operator/=( DenseMatrix<MT,SO>&& mat, ST scalar )
398 {
399  return operator/=( ~mat, scalar );
400 }
401 //*************************************************************************************************
402 
403 
404 
405 
406 //=================================================================================================
407 //
408 // GLOBAL FUNCTIONS
409 //
410 //=================================================================================================
411 
412 //*************************************************************************************************
415 template< typename MT, bool SO >
416 bool isnan( const DenseMatrix<MT,SO>& dm );
417 
418 template< bool RF, typename MT, bool SO >
419 bool isSymmetric( const DenseMatrix<MT,SO>& dm );
420 
421 template< bool RF, typename MT, bool SO >
422 bool isHermitian( const DenseMatrix<MT,SO>& dm );
423 
424 template< bool RF, typename MT, bool SO >
425 bool isUniform( const DenseMatrix<MT,SO>& dm );
426 
427 template< bool RF, typename MT, bool SO >
428 bool isZero( const DenseMatrix<MT,SO>& dm );
429 
430 template< bool RF, typename MT, bool SO >
431 bool isLower( const DenseMatrix<MT,SO>& dm );
432 
433 template< bool RF, typename MT, bool SO >
434 bool isUniLower( const DenseMatrix<MT,SO>& dm );
435 
436 template< bool RF, typename MT, bool SO >
437 bool isStrictlyLower( const DenseMatrix<MT,SO>& dm );
438 
439 template< bool RF, typename MT, bool SO >
440 bool isUpper( const DenseMatrix<MT,SO>& dm );
441 
442 template< bool RF, typename MT, bool SO >
443 bool isUniUpper( const DenseMatrix<MT,SO>& dm );
444 
445 template< bool RF, typename MT, bool SO >
446 bool isStrictlyUpper( const DenseMatrix<MT,SO>& dm );
447 
448 template< bool RF, typename MT, bool SO >
449 bool isDiagonal( const DenseMatrix<MT,SO>& dm );
450 
451 template< bool RF, typename MT, bool SO >
452 bool isIdentity( const DenseMatrix<MT,SO>& dm );
454 //*************************************************************************************************
455 
456 
457 //*************************************************************************************************
477 template< typename MT // Type of the dense matrix
478  , bool SO > // Storage order
479 bool isnan( const DenseMatrix<MT,SO>& dm )
480 {
481  using CT = CompositeType_t<MT>;
482 
483  CT A( ~dm ); // Evaluation of the dense matrix operand
484 
485  if( SO == rowMajor ) {
486  for( size_t i=0UL; i<A.rows(); ++i ) {
487  for( size_t j=0UL; j<A.columns(); ++j )
488  if( isnan( A(i,j) ) ) return true;
489  }
490  }
491  else {
492  for( size_t j=0UL; j<A.columns(); ++j ) {
493  for( size_t i=0UL; i<A.rows(); ++i )
494  if( isnan( A(i,j) ) ) return true;
495  }
496  }
497 
498  return false;
499 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
536 template< bool RF // Relaxation flag
537  , typename MT // Type of the dense matrix
538  , bool SO > // Storage order
540 {
541  using CT = CompositeType_t<MT>;
542 
543  if( IsSymmetric_v<MT> )
544  return true;
545 
546  if( !isSquare( ~dm ) )
547  return false;
548 
549  if( IsUniform_v<MT> || (~dm).rows() < 2UL )
550  return true;
551 
552  if( IsTriangular_v<MT> )
553  return isDiagonal( ~dm );
554 
555  CT A( ~dm ); // Evaluation of the dense matrix operand
556 
557  if( SO == rowMajor ) {
558  for( size_t i=1UL; i<A.rows(); ++i ) {
559  for( size_t j=0UL; j<i; ++j ) {
560  if( !equal<RF>( A(i,j), A(j,i) ) )
561  return false;
562  }
563  }
564  }
565  else {
566  for( size_t j=1UL; j<A.columns(); ++j ) {
567  for( size_t i=0UL; i<j; ++i ) {
568  if( !equal<RF>( A(i,j), A(j,i) ) )
569  return false;
570  }
571  }
572  }
573 
574  return true;
575 }
576 //*************************************************************************************************
577 
578 
579 //*************************************************************************************************
614 template< bool RF // Relaxation flag
615  , typename MT // Type of the dense matrix
616  , bool SO > // Storage order
618 {
619  using ET = ElementType_t<MT>;
620  using CT = CompositeType_t<MT>;
621 
622  if( IsHermitian_v<MT> )
623  return true;
624 
625  if( !IsNumeric_v<ET> || !isSquare( ~dm ) )
626  return false;
627 
628  if( IsBuiltin_v<ET> && IsUniform_v<MT> )
629  return true;
630 
631  CT A( ~dm ); // Evaluation of the dense matrix operand
632 
633  if( SO == rowMajor ) {
634  for( size_t i=0UL; i<A.rows(); ++i ) {
635  for( size_t j=0UL; j<i; ++j ) {
636  if( !equal<RF>( A(i,j), conj( A(j,i) ) ) )
637  return false;
638  }
639  if( !isReal<RF>( A(i,i) ) )
640  return false;
641  }
642  }
643  else {
644  for( size_t j=0UL; j<A.columns(); ++j ) {
645  for( size_t i=0UL; i<j; ++i ) {
646  if( !equal<RF>( A(i,j), conj( A(j,i) ) ) )
647  return false;
648  }
649  if( !isReal<RF>( A(j,j) ) )
650  return false;
651  }
652  }
653 
654  return true;
655 }
656 //*************************************************************************************************
657 
658 
659 //*************************************************************************************************
667 template< bool RF // Relaxation flag
668  , typename MT > // Type of the dense matrix
669 bool isUniform_backend( const DenseMatrix<MT,false>& dm, TrueType )
670 {
673 
674  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
675  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
676 
677  const size_t ibegin( ( IsStrictlyLower_v<MT> )?( 1UL ):( 0UL ) );
678  const size_t iend ( ( IsStrictlyUpper_v<MT> )?( (~dm).rows()-1UL ):( (~dm).rows() ) );
679 
680  for( size_t i=ibegin; i<iend; ++i ) {
681  if( !IsUpper_v<MT> ) {
682  for( size_t j=0UL; j<i; ++j ) {
683  if( !isDefault<RF>( (~dm)(i,j) ) )
684  return false;
685  }
686  }
687  if( !isDefault<RF>( (~dm)(i,i) ) )
688  return false;
689  if( !IsLower_v<MT> ) {
690  for( size_t j=i+1UL; j<(~dm).columns(); ++j ) {
691  if( !isDefault<RF>( (~dm)(i,j) ) )
692  return false;
693  }
694  }
695  }
696 
697  return true;
698 }
700 //*************************************************************************************************
701 
702 
703 //*************************************************************************************************
711 template< bool RF // Relaxation flag
712  , typename MT > // Type of the dense matrix
713 bool isUniform_backend( const DenseMatrix<MT,true>& dm, TrueType )
714 {
717 
718  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
719  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
720 
721  const size_t jbegin( ( IsStrictlyUpper_v<MT> )?( 1UL ):( 0UL ) );
722  const size_t jend ( ( IsStrictlyLower_v<MT> )?( (~dm).columns()-1UL ):( (~dm).columns() ) );
723 
724  for( size_t j=jbegin; j<jend; ++j ) {
725  if( !IsLower_v<MT> ) {
726  for( size_t i=0UL; i<j; ++i ) {
727  if( !isDefault<RF>( (~dm)(i,j) ) )
728  return false;
729  }
730  }
731  if( !isDefault<RF>( (~dm)(j,j) ) )
732  return false;
733  if( !IsUpper_v<MT> ) {
734  for( size_t i=j+1UL; i<(~dm).rows(); ++i ) {
735  if( !isDefault<RF>( (~dm)(i,j) ) )
736  return false;
737  }
738  }
739  }
740 
741  return true;
742 }
744 //*************************************************************************************************
745 
746 
747 //*************************************************************************************************
755 template< bool RF // Relaxation flag
756  , typename MT > // Type of the dense matrix
757 bool isUniform_backend( const DenseMatrix<MT,false>& dm, FalseType )
758 {
761 
762  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
763  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
764 
765  const auto& cmp( (~dm)(0UL,0UL) );
766 
767  for( size_t i=0UL; i<(~dm).rows(); ++i ) {
768  for( size_t j=0UL; j<(~dm).columns(); ++j ) {
769  if( !equal<RF>( (~dm)(i,j), cmp ) )
770  return false;
771  }
772  }
773 
774  return true;
775 }
777 //*************************************************************************************************
778 
779 
780 //*************************************************************************************************
788 template< bool RF // Relaxation flag
789  , typename MT > // Type of the dense matrix
790 bool isUniform_backend( const DenseMatrix<MT,true>& dm, FalseType )
791 {
794 
795  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
796  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
797 
798  const auto& cmp( (~dm)(0UL,0UL) );
799 
800  for( size_t j=0UL; j<(~dm).columns(); ++j ) {
801  for( size_t i=0UL; i<(~dm).rows(); ++i ) {
802  if( !equal<RF>( (~dm)(i,j), cmp ) )
803  return false;
804  }
805  }
806 
807  return true;
808 }
810 //*************************************************************************************************
811 
812 
813 //*************************************************************************************************
846 template< bool RF // Relaxation flag
847  , typename MT // Type of the dense matrix
848  , bool SO > // Storage order
849 bool isUniform( const DenseMatrix<MT,SO>& dm )
850 {
851  if( IsUniform_v<MT> ||
852  (~dm).rows() == 0UL || (~dm).columns() == 0UL ||
853  ( (~dm).rows() == 1UL && (~dm).columns() == 1UL ) )
854  return true;
855 
856  if( IsUniTriangular_v<MT> )
857  return false;
858 
859  CompositeType_t<MT> A( ~dm ); // Evaluation of the dense matrix operand
860 
861  return isUniform_backend<RF>( A, typename IsTriangular<MT>::Type() );
862 }
863 //*************************************************************************************************
864 
865 
866 //*************************************************************************************************
899 template< bool RF // Relaxation flag
900  , typename MT // Type of the dense matrix
901  , bool SO > // Storage order
902 bool isZero( const DenseMatrix<MT,SO>& dm )
903 {
904  const size_t M( (~dm).rows() );
905  const size_t N( (~dm).columns() );
906 
907  if( IsZero_v<MT> || M == 0UL || N == 0UL )
908  return true;
909 
910  if( IsUniTriangular_v<MT> )
911  return false;
912 
913  if( IsUniform_v<MT> )
914  return isZero<RF>( (~dm)(0UL,0UL) );
915 
916  CompositeType_t<MT> A( ~dm ); // Evaluation of the dense matrix operand
917 
918  if( SO == rowMajor )
919  {
920  for( size_t i=0UL; i<M; ++i )
921  {
922  const size_t jbegin( IsUpper_v<MT>
923  ? ( IsStrictlyUpper_v<MT> ? i+1UL : i )
924  : 0UL );
925  const size_t jend ( IsLower_v<MT> || IsSymmetric_v<MT> || IsHermitian_v<MT>
926  ? ( IsStrictlyLower_v<MT> ? i : i+1UL )
927  : N );
928 
929  for( size_t j=jbegin; j<jend; ++j ) {
930  if( !isZero<RF>( A(i,j) ) )
931  return false;
932  }
933  }
934  }
935  else
936  {
937  for( size_t j=0UL; j<N; ++j )
938  {
939  const size_t ibegin( IsLower_v<MT>
940  ? ( IsStrictlyLower_v<MT> ? j+1UL : j )
941  : 0UL );
942  const size_t iend ( IsUpper_v<MT> || IsSymmetric_v<MT> || IsHermitian_v<MT>
943  ? ( IsStrictlyUpper_v<MT> ? j : j+1UL )
944  : M );
945 
946  for( size_t i=ibegin; i<iend; ++i ) {
947  if( !isZero<RF>( A(i,j) ) )
948  return false;
949  }
950  }
951  }
952 
953  return true;
954 }
955 //*************************************************************************************************
956 
957 
958 //*************************************************************************************************
1001 template< bool RF // Relaxation flag
1002  , typename MT // Type of the dense matrix
1003  , bool SO > // Storage order
1004 bool isLower( const DenseMatrix<MT,SO>& dm )
1005 {
1006  using RT = ResultType_t<MT>;
1007  using RN = ReturnType_t<MT>;
1008  using CT = CompositeType_t<MT>;
1009  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1010 
1011  if( IsLower_v<MT> )
1012  return true;
1013 
1014  if( !isSquare( ~dm ) )
1015  return false;
1016 
1017  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1018  return true;
1019 
1020  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1021 
1022  if( IsUniform_v<MT> )
1023  return isDefault<RF>( A(0UL,0UL) );
1024 
1025  if( SO == rowMajor ) {
1026  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
1027  for( size_t j=i+1UL; j<A.columns(); ++j ) {
1028  if( !isDefault<RF>( A(i,j) ) )
1029  return false;
1030  }
1031  }
1032  }
1033  else {
1034  for( size_t j=1UL; j<A.columns(); ++j ) {
1035  for( size_t i=0UL; i<j; ++i ) {
1036  if( !isDefault<RF>( A(i,j) ) )
1037  return false;
1038  }
1039  }
1040  }
1041 
1042  return true;
1043 }
1044 //*************************************************************************************************
1045 
1046 
1047 //*************************************************************************************************
1089 template< bool RF // Relaxation flag
1090  , typename MT // Type of the dense matrix
1091  , bool SO > // Storage order
1093 {
1094  using RT = ResultType_t<MT>;
1095  using RN = ReturnType_t<MT>;
1096  using CT = CompositeType_t<MT>;
1097  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1098 
1099  if( IsUniLower_v<MT> )
1100  return true;
1101 
1102  if( !isSquare( ~dm ) )
1103  return false;
1104 
1105  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1106 
1107  if( SO == rowMajor ) {
1108  for( size_t i=0UL; i<A.rows(); ++i ) {
1109  if( !isOne<RF>( A(i,i) ) )
1110  return false;
1111  for( size_t j=i+1UL; j<A.columns(); ++j ) {
1112  if( !isZero<RF>( A(i,j) ) )
1113  return false;
1114  }
1115  }
1116  }
1117  else {
1118  for( size_t j=0UL; j<A.columns(); ++j ) {
1119  for( size_t i=0UL; i<j; ++i ) {
1120  if( !isZero<RF>( A(i,j) ) )
1121  return false;
1122  }
1123  if( !isOne<RF>( A(j,j) ) )
1124  return false;
1125  }
1126  }
1127 
1128  return true;
1129 }
1130 //*************************************************************************************************
1131 
1132 
1133 //*************************************************************************************************
1176 template< bool RF // Relaxation flag
1177  , typename MT // Type of the dense matrix
1178  , bool SO > // Storage order
1180 {
1181  using RT = ResultType_t<MT>;
1182  using RN = ReturnType_t<MT>;
1183  using CT = CompositeType_t<MT>;
1184  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1185 
1186  if( IsStrictlyLower_v<MT> )
1187  return true;
1188 
1189  if( !isSquare( ~dm ) )
1190  return false;
1191 
1192  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1193  return true;
1194 
1195  if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1196  return false;
1197 
1198  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1199 
1200  if( IsUniform_v<MT> )
1201  return isDefault<RF>( A(0UL,0UL) );
1202 
1203  if( SO == rowMajor ) {
1204  for( size_t i=0UL; i<A.rows(); ++i ) {
1205  for( size_t j=i; j<A.columns(); ++j ) {
1206  if( !isDefault<RF>( A(i,j) ) )
1207  return false;
1208  }
1209  }
1210  }
1211  else {
1212  for( size_t j=0UL; j<A.columns(); ++j ) {
1213  for( size_t i=0UL; i<=j; ++i ) {
1214  if( !isDefault<RF>( A(i,j) ) )
1215  return false;
1216  }
1217  }
1218  }
1219 
1220  return true;
1221 }
1222 //*************************************************************************************************
1223 
1224 
1225 //*************************************************************************************************
1268 template< bool RF // Relaxation flag
1269  , typename MT // Type of the dense matrix
1270  , bool SO > // Storage order
1271 bool isUpper( const DenseMatrix<MT,SO>& dm )
1272 {
1273  using RT = ResultType_t<MT>;
1274  using RN = ReturnType_t<MT>;
1275  using CT = CompositeType_t<MT>;
1276  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1277 
1278  if( IsUpper_v<MT> )
1279  return true;
1280 
1281  if( !isSquare( ~dm ) )
1282  return false;
1283 
1284  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1285  return true;
1286 
1287  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1288 
1289  if( IsUniform_v<MT> )
1290  return isDefault<RF>( A(0UL,0UL) );
1291 
1292  if( SO == rowMajor ) {
1293  for( size_t i=1UL; i<A.rows(); ++i ) {
1294  for( size_t j=0UL; j<i; ++j ) {
1295  if( !isDefault<RF>( A(i,j) ) )
1296  return false;
1297  }
1298  }
1299  }
1300  else {
1301  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
1302  for( size_t i=j+1UL; i<A.rows(); ++i ) {
1303  if( !isDefault<RF>( A(i,j) ) )
1304  return false;
1305  }
1306  }
1307  }
1308 
1309  return true;
1310 }
1311 //*************************************************************************************************
1312 
1313 
1314 //*************************************************************************************************
1356 template< bool RF // Relaxation flag
1357  , typename MT // Type of the dense matrix
1358  , bool SO > // Storage order
1360 {
1361  using RT = ResultType_t<MT>;
1362  using RN = ReturnType_t<MT>;
1363  using CT = CompositeType_t<MT>;
1364  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1365 
1366  if( IsUniUpper_v<MT> )
1367  return true;
1368 
1369  if( !isSquare( ~dm ) )
1370  return false;
1371 
1372  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1373 
1374  if( SO == rowMajor ) {
1375  for( size_t i=0UL; i<A.rows(); ++i ) {
1376  for( size_t j=0UL; j<i; ++j ) {
1377  if( !isZero<RF>( A(i,j) ) )
1378  return false;
1379  }
1380  if( !isOne<RF>( A(i,i) ) )
1381  return false;
1382  }
1383  }
1384  else {
1385  for( size_t j=0UL; j<A.columns(); ++j ) {
1386  if( !isOne<RF>( A(j,j) ) )
1387  return false;
1388  for( size_t i=j+1UL; i<A.rows(); ++i ) {
1389  if( !isZero<RF>( A(i,j) ) )
1390  return false;
1391  }
1392  }
1393  }
1394 
1395  return true;
1396 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1443 template< bool RF // Relaxation flag
1444  , typename MT // Type of the dense matrix
1445  , bool SO > // Storage order
1447 {
1448  using RT = ResultType_t<MT>;
1449  using RN = ReturnType_t<MT>;
1450  using CT = CompositeType_t<MT>;
1451  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1452 
1453  if( IsStrictlyUpper_v<MT> )
1454  return true;
1455 
1456  if( !isSquare( ~dm ) )
1457  return false;
1458 
1459  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1460  return true;
1461 
1462  if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1463  return false;
1464 
1465  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1466 
1467  if( IsUniform_v<MT> )
1468  return isDefault<RF>( A(0UL,0UL) );
1469 
1470  if( SO == rowMajor ) {
1471  for( size_t i=0UL; i<A.rows(); ++i ) {
1472  for( size_t j=0UL; j<=i; ++j ) {
1473  if( !isDefault<RF>( A(i,j) ) )
1474  return false;
1475  }
1476  }
1477  }
1478  else {
1479  for( size_t j=0UL; j<A.columns(); ++j ) {
1480  for( size_t i=j; i<A.rows(); ++i ) {
1481  if( !isDefault<RF>( A(i,j) ) )
1482  return false;
1483  }
1484  }
1485  }
1486 
1487  return true;
1488 }
1489 //*************************************************************************************************
1490 
1491 
1492 //*************************************************************************************************
1536 template< bool RF // Relaxation flag
1537  , typename MT // Type of the dense matrix
1538  , bool SO > // Storage order
1540 {
1541  using RT = ResultType_t<MT>;
1542  using RN = ReturnType_t<MT>;
1543  using CT = CompositeType_t<MT>;
1544  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1545 
1546  if( IsDiagonal_v<MT> )
1547  return true;
1548 
1549  if( !isSquare( ~dm ) )
1550  return false;
1551 
1552  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1553  return true;
1554 
1555  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1556 
1557  if( IsUniform_v<MT> )
1558  return isDefault<RF>( A(0UL,0UL) );
1559 
1560  if( SO == rowMajor ) {
1561  for( size_t i=0UL; i<A.rows(); ++i ) {
1562  if( !IsUpper_v<MT> ) {
1563  for( size_t j=0UL; j<i; ++j ) {
1564  if( !isDefault<RF>( A(i,j) ) )
1565  return false;
1566  }
1567  }
1568  if( !IsLower_v<MT> ) {
1569  for( size_t j=i+1UL; j<A.columns(); ++j ) {
1570  if( !isDefault<RF>( A(i,j) ) )
1571  return false;
1572  }
1573  }
1574  }
1575  }
1576  else {
1577  for( size_t j=0UL; j<A.columns(); ++j ) {
1578  if( !IsLower_v<MT> ) {
1579  for( size_t i=0UL; i<j; ++i ) {
1580  if( !isDefault<RF>( A(i,j) ) )
1581  return false;
1582  }
1583  }
1584  if( !IsUpper_v<MT> ) {
1585  for( size_t i=j+1UL; i<A.rows(); ++i ) {
1586  if( !isDefault<RF>( A(i,j) ) )
1587  return false;
1588  }
1589  }
1590  }
1591  }
1592 
1593  return true;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1641 template< bool RF // Relaxation flag
1642  , typename MT // Type of the dense matrix
1643  , bool SO > // Storage order
1645 {
1646  using RT = ResultType_t<MT>;
1647  using RN = ReturnType_t<MT>;
1648  using CT = CompositeType_t<MT>;
1649  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1650 
1651  if( IsIdentity_v<MT> )
1652  return true;
1653 
1654  if( !isSquare( ~dm ) )
1655  return false;
1656 
1657  if( (~dm).rows() == 0UL )
1658  return true;
1659 
1660  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1661 
1662  if( SO == rowMajor ) {
1663  for( size_t i=0UL; i<A.rows(); ++i ) {
1664  if( !IsUpper_v<MT> ) {
1665  for( size_t j=0UL; j<i; ++j ) {
1666  if( !isZero<RF>( A(i,j) ) )
1667  return false;
1668  }
1669  }
1670  if( !IsUniLower_v<MT> && !IsUniUpper_v<MT> && !isOne<RF>( A(i,i) ) ) {
1671  return false;
1672  }
1673  if( !IsLower_v<MT> ) {
1674  for( size_t j=i+1UL; j<A.columns(); ++j ) {
1675  if( !isZero<RF>( A(i,j) ) )
1676  return false;
1677  }
1678  }
1679  }
1680  }
1681  else {
1682  for( size_t j=0UL; j<A.columns(); ++j ) {
1683  if( !IsLower_v<MT> ) {
1684  for( size_t i=0UL; i<j; ++i ) {
1685  if( !isZero<RF>( A(i,j) ) )
1686  return false;
1687  }
1688  }
1689  if( !IsUniLower_v<MT> && !IsUniUpper_v<MT> && !isOne<RF>( A(j,j) ) ) {
1690  return false;
1691  }
1692  if( !IsUpper_v<MT> ) {
1693  for( size_t i=j+1UL; i<A.rows(); ++i ) {
1694  if( !isZero<RF>( A(i,j) ) )
1695  return false;
1696  }
1697  }
1698  }
1699  }
1700 
1701  return true;
1702 }
1703 //*************************************************************************************************
1704 
1705 } // namespace blaze
1706 
1707 #endif
#define BLAZE_CONSTRAINT_MUST_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a lower or upper triangular matrix t...
Definition: Triangular.h:61
Header file for the isnan shim.
BoolConstant< false > FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Header file for the blaze::checked and blaze::unchecked instances.
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1004
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1271
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1179
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:354
Header file for the IsUniUpper type trait.
Compile time check for triangular matrix types.This type trait tests whether or not the given templat...
Definition: IsTriangular.h:86
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper triangular matrix type...
Definition: Triangular.h:81
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias declaration for the If class template.The If_t alias declaration provides a convenien...
Definition: If.h:109
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the FalseType type/value trait base class.
Header file for the isZero shim.
Header file for the IsDiagonal type trait.
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1092
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
Header file for the IsIdentity type trait.
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1539
Header file for the decltype(auto) workaround.
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
Header file for the IsUniLower type trait.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
bool isIdentity(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is an identity matrix.
Definition: DenseMatrix.h:1644
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:673
Header file for the matrix storage order types.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
Constraint on the data type.
Header file for the IsUniform type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
Header file for the DenseMatrix base class.
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:253
Header file for the IsLower type trait.
Header file for the equal shim.
Header file for the IsUniTriangular type trait.
Header file for the IsTriangular type trait.
bool isnan(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is not a number.
Definition: DiagonalProxy.h:713
bool isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:849
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Header file for the isOne shim.
Header file for the conjugate shim.
Constraint on the data type.
Header file for the IsNumeric type trait.
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1446
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
Header file for the IsZero type trait.
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:617
Header file for the isDefault shim.
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 isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:539
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
Header file for the IsBuiltin type trait.
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:290
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:1359
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
Header file for the IsUpper type trait.
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1326
Header file for the IsHermitian type trait.
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
Header file for the IsRestricted type trait.
Header file for the isReal shim.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
bool equal(const SharedValue< T1 > &lhs, const SharedValue< T2 > &rhs)
Equality check for a two shared values.
Definition: SharedValue.h:342
Header file for the reduction flags.
Header file for the TrueType type/value trait base class.
Header file for the IsExpression type trait class.