Blaze  3.6
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>
75 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/mpl/If.h>
78 #include <blaze/util/Types.h>
81 
82 
83 namespace blaze {
84 
85 //=================================================================================================
86 //
87 // GLOBAL OPERATORS
88 //
89 //=================================================================================================
90 
91 //*************************************************************************************************
94 template< typename T1, typename T2 >
95 auto operator==( const DenseMatrix<T1,false>& mat, T2 scalar )
96  -> EnableIf_t< IsNumeric_v<T2>, bool >;
97 
98 template< typename T1, typename T2 >
99 auto operator==( const DenseMatrix<T1,true>& mat, T2 scalar )
100  -> EnableIf_t< IsNumeric_v<T2>, bool >;
101 
102 template< typename T1, typename T2, bool SO >
103 auto operator==( T1 scalar, const DenseMatrix<T2,SO>& mat )
104  -> EnableIf_t< IsNumeric_v<T2>, bool >;
105 
106 template< typename T1, typename T2, bool SO >
107 auto operator!=( const DenseMatrix<T1,SO>& mat, T2 scalar )
108  -> EnableIf_t< IsNumeric_v<T2>, bool >;
109 
110 template< typename T1, typename T2, bool SO >
111 auto operator!=( T1 scalar, const DenseMatrix<T2,SO>& mat )
112  -> EnableIf_t< IsNumeric_v<T2>, bool >;
113 
114 template< typename MT, bool SO, typename ST >
115 auto operator+=( DenseMatrix<MT,SO>& mat, ST scalar )
116  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
117 
118 template< typename MT, bool SO, typename ST >
119 auto operator+=( DenseMatrix<MT,SO>&& mat, ST scalar )
120  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
121 
122 template< typename MT, bool SO, typename ST >
123 auto operator-=( DenseMatrix<MT,SO>& mat, ST scalar )
124  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
125 
126 template< typename MT, bool SO, typename ST >
127 auto operator-=( DenseMatrix<MT,SO>&& mat, ST scalar )
128  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
129 
130 template< typename MT, bool SO, typename ST >
131 auto operator*=( DenseMatrix<MT,SO>& mat, ST scalar )
132  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
133 
134 template< typename MT, bool SO, typename ST >
135 auto operator*=( DenseMatrix<MT,SO>&& mat, ST scalar )
136  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
137 
138 template< typename MT, bool SO, typename ST >
139 auto operator/=( DenseMatrix<MT,SO>& mat, ST scalar )
140  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
141 
142 template< typename MT, bool SO, typename ST >
143 auto operator/=( DenseMatrix<MT,SO>&& mat, ST scalar )
144  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
145 
146 template< typename MT, bool SO >
147 MT& operator<<=( DenseMatrix<MT,SO>& mat, int count );
148 
149 template< typename MT, bool SO >
150 MT& operator<<=( DenseMatrix<MT,SO>&& mat, int count );
151 
152 template< typename MT1, bool SO1, typename MT2, bool SO2 >
153 MT1& operator<<=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
154 
155 template< typename MT1, bool SO1, typename MT2, bool SO2 >
156 MT1& operator<<=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
157 
158 template< typename MT, bool SO >
159 MT& operator>>=( DenseMatrix<MT,SO>& mat, int count );
160 
161 template< typename MT, bool SO >
162 MT& operator>>=( DenseMatrix<MT,SO>&& mat, int count );
163 
164 template< typename MT1, bool SO1, typename MT2, bool SO2 >
165 MT1& operator>>=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
166 
167 template< typename MT1, bool SO1, typename MT2, bool SO2 >
168 MT1& operator>>=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
169 
170 template< typename MT, bool SO, typename ST >
171 auto operator&=( DenseMatrix<MT,SO>& mat, ST scalar )
172  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
173 
174 template< typename MT, bool SO, typename ST >
175 auto operator&=( DenseMatrix<MT,SO>&& mat, ST scalar )
176  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
177 
178 template< typename MT1, bool SO1, typename MT2, bool SO2 >
179 MT1& operator&=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
180 
181 template< typename MT1, bool SO1, typename MT2, bool SO2 >
182 MT1& operator&=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
183 
184 template< typename MT, bool SO, typename ST >
185 auto operator|=( DenseMatrix<MT,SO>& mat, ST scalar )
186  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
187 
188 template< typename MT, bool SO, typename ST >
189 auto operator|=( DenseMatrix<MT,SO>&& mat, ST scalar )
190  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
191 
192 template< typename MT1, bool SO1, typename MT2, bool SO2 >
193 MT1& operator|=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
194 
195 template< typename MT1, bool SO1, typename MT2, bool SO2 >
196 MT1& operator|=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
197 
198 template< typename MT, bool SO, typename ST >
199 auto operator^=( DenseMatrix<MT,SO>& mat, ST scalar )
200  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
201 
202 template< typename MT, bool SO, typename ST >
203 auto operator^=( DenseMatrix<MT,SO>&& mat, ST scalar )
204  -> EnableIf_t< IsNumeric_v<ST>, MT& >;
205 
206 template< typename MT1, bool SO1, typename MT2, bool SO2 >
207 MT1& operator^=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs );
208 
209 template< typename MT1, bool SO1, typename MT2, bool SO2 >
210 MT1& operator^=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs );
212 //*************************************************************************************************
213 
214 
215 //*************************************************************************************************
227 template< typename T1 // Type of the left-hand side dense matrix
228  , typename T2 > // Type of the right-hand side scalar
229 inline auto operator==( const DenseMatrix<T1,false>& mat, T2 scalar )
230  -> EnableIf_t< IsNumeric_v<T2>, bool >
231 {
232  using CT1 = CompositeType_t<T1>;
233 
234  // Evaluation of the dense matrix operand
235  CT1 A( ~mat );
236 
237  // In order to compare the matrix and the scalar value, the data values of the lower-order
238  // data type are converted to the higher-order data type within the equal function.
239  for( size_t i=0; i<A.rows(); ++i ) {
240  for( size_t j=0; j<A.columns(); ++j ) {
241  if( !equal( A(i,j), scalar ) ) return false;
242  }
243  }
244 
245  return true;
246 }
247 //*************************************************************************************************
248 
249 
250 //*************************************************************************************************
262 template< typename T1 // Type of the left-hand side dense matrix
263  , typename T2 > // Type of the right-hand side scalar
264 inline auto operator==( const DenseMatrix<T1,true>& mat, T2 scalar )
265  -> EnableIf_t< IsNumeric_v<T2>, bool >
266 {
267  using CT1 = CompositeType_t<T1>;
268 
269  // Evaluation of the dense matrix operand
270  CT1 A( ~mat );
271 
272  // In order to compare the matrix and the scalar value, the data values of the lower-order
273  // data type are converted to the higher-order data type within the equal function.
274  for( size_t j=0; j<A.columns(); ++j ) {
275  for( size_t i=0; i<A.rows(); ++i ) {
276  if( !equal( A(i,j), scalar ) ) return false;
277  }
278  }
279 
280  return true;
281 }
282 //*************************************************************************************************
283 
284 
285 //*************************************************************************************************
297 template< typename T1 // Type of the left-hand side scalar
298  , typename T2 // Type of the right-hand side dense matrix
299  , bool SO > // Storage order
300 inline auto operator==( T1 scalar, const DenseMatrix<T2,SO>& mat )
301  -> EnableIf_t< IsNumeric_v<T1>, bool >
302 {
303  return ( mat == scalar );
304 }
305 //*************************************************************************************************
306 
307 
308 //*************************************************************************************************
320 template< typename T1 // Type of the left-hand side dense matrix
321  , typename T2 // Type of the right-hand side scalar
322  , bool SO > // Storage order
323 inline auto operator!=( const DenseMatrix<T1,SO>& mat, T2 scalar )
324  -> EnableIf_t< IsNumeric_v<T2>, bool >
325 {
326  return !( mat == scalar );
327 }
328 //*************************************************************************************************
329 
330 
331 //*************************************************************************************************
343 template< typename T1 // Type of the left-hand side scalar
344  , typename T2 // Type of the right-hand side dense matrix
345  , bool SO > // Storage order
346 inline auto operator!=( T1 scalar, const DenseMatrix<T2,SO>& mat )
347  -> EnableIf_t< IsNumeric_v<T1>, bool >
348 {
349  return !( mat == scalar );
350 }
351 //*************************************************************************************************
352 
353 
354 //*************************************************************************************************
367 template< typename MT // Type of the left-hand side dense matrix
368  , bool SO // Storage order
369  , typename ST > // Data type of the right-hand side scalar
370 inline auto operator+=( DenseMatrix<MT,SO>& mat, ST scalar )
372 {
374 
375  if( IsRestricted_v<MT> ) {
376  if( !tryAdd( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
377  BLAZE_THROW_INVALID_ARGUMENT( "Invalid addition to restricted matrix" );
378  }
379  }
380 
381  decltype(auto) left( derestrict( ~mat ) );
382 
383  smpAssign( left, left + scalar );
384 
385  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
386 
387  return ~mat;
388 }
389 //*************************************************************************************************
390 
391 
392 //*************************************************************************************************
405 template< typename MT // Type of the left-hand side dense matrix
406  , bool SO // Storage order
407  , typename ST > // Data type of the right-hand side scalar
408 inline auto operator+=( DenseMatrix<MT,SO>&& mat, ST scalar )
410 {
411  return operator+=( ~mat, scalar );
412 }
413 //*************************************************************************************************
414 
415 
416 //*************************************************************************************************
429 template< typename MT // Type of the left-hand side dense matrix
430  , bool SO // Storage order
431  , typename ST > // Data type of the right-hand side scalar
432 inline auto operator-=( DenseMatrix<MT,SO>& mat, ST scalar )
434 {
436 
437  if( IsRestricted_v<MT> ) {
438  if( !trySub( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
439  BLAZE_THROW_INVALID_ARGUMENT( "Invalid subtraction from restricted matrix" );
440  }
441  }
442 
443  decltype(auto) left( derestrict( ~mat ) );
444 
445  smpAssign( left, left - scalar );
446 
447  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
448 
449  return ~mat;
450 }
451 //*************************************************************************************************
452 
453 
454 //*************************************************************************************************
467 template< typename MT // Type of the left-hand side dense matrix
468  , bool SO // Storage order
469  , typename ST > // Data type of the right-hand side scalar
470 inline auto operator-=( DenseMatrix<MT,SO>&& mat, ST scalar )
472 {
473  return operator-=( ~mat, scalar );
474 }
475 //*************************************************************************************************
476 
477 
478 //*************************************************************************************************
491 template< typename MT // Type of the left-hand side dense matrix
492  , bool SO // Storage order
493  , typename ST > // Data type of the right-hand side scalar
494 inline auto operator*=( DenseMatrix<MT,SO>& mat, ST scalar )
496 {
498 
499  if( IsRestricted_v<MT> ) {
500  if( !tryMult( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
501  BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
502  }
503  }
504 
505  decltype(auto) left( derestrict( ~mat ) );
506 
507  smpAssign( left, left * scalar );
508 
509  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
510 
511  return ~mat;
512 }
513 //*************************************************************************************************
514 
515 
516 //*************************************************************************************************
529 template< typename MT // Type of the left-hand side dense matrix
530  , bool SO // Storage order
531  , typename ST > // Data type of the right-hand side scalar
532 inline auto operator*=( DenseMatrix<MT,SO>&& mat, ST scalar )
534 {
535  return operator*=( ~mat, scalar );
536 }
537 //*************************************************************************************************
538 
539 
540 //*************************************************************************************************
555 template< typename MT // Type of the left-hand side dense matrix
556  , bool SO // Storage order
557  , typename ST > // Data type of the right-hand side scalar
558 inline auto operator/=( DenseMatrix<MT,SO>& mat, ST scalar )
560 {
562 
563  BLAZE_USER_ASSERT( !isZero( scalar ), "Division by zero detected" );
564 
565  if( IsRestricted_v<MT> ) {
566  if( !tryDiv( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
567  BLAZE_THROW_INVALID_ARGUMENT( "Invalid scaling of restricted matrix" );
568  }
569  }
570 
571  decltype(auto) left( derestrict( ~mat ) );
572 
573  smpAssign( left, left / scalar );
574 
575  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
576 
577  return ~mat;
578 }
579 //*************************************************************************************************
580 
581 
582 //*************************************************************************************************
597 template< typename MT // Type of the left-hand side dense matrix
598  , bool SO // Storage order
599  , typename ST > // Data type of the right-hand side scalar
600 inline auto operator/=( DenseMatrix<MT,SO>&& mat, ST scalar )
602 {
603  return operator/=( ~mat, scalar );
604 }
605 //*************************************************************************************************
606 
607 
608 //*************************************************************************************************
620 template< typename MT // Type of the dense matrix
621  , bool SO > // Storage order
622 inline MT& operator<<=( DenseMatrix<MT,SO>& mat, int count )
623 {
625 
626  if( IsRestricted_v<MT> ) {
627  if( !tryShift( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), count ) ) {
628  BLAZE_THROW_INVALID_ARGUMENT( "Invalid left-shift of restricted matrix" );
629  }
630  }
631 
632  decltype(auto) left( derestrict( ~mat ) );
633 
634  smpAssign( left, left << count );
635 
636  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
637 
638  return ~mat;
639 }
640 //*************************************************************************************************
641 
642 
643 //*************************************************************************************************
655 template< typename MT // Type of the dense matrix
656  , bool SO > // Storage order
657 inline MT& operator<<=( DenseMatrix<MT,SO>&& mat, int count )
658 {
659  return operator<<=( ~mat, count );
660 }
661 //*************************************************************************************************
662 
663 
664 //*************************************************************************************************
676 template< typename MT1 // Type of the left-hand side dense matrix
677  , bool SO1 // Storage order of the left-hand side dense matrix
678  , typename MT2 // Type of the right-hand side dense matrix
679  , bool SO2 > // Storage order of the right-hand side dense matrix
681 {
682  if( IsRestricted_v<MT1> ) {
683  if( !tryShiftAssign( ~lhs, ~rhs, 0UL, 0UL ) ) {
684  BLAZE_THROW_INVALID_ARGUMENT( "Invalid left-shift of restricted matrix" );
685  }
686  }
687 
688  decltype(auto) left( derestrict( ~lhs ) );
689 
690  smpAssign( left, left << (~rhs) );
691 
692  BLAZE_INTERNAL_ASSERT( isIntact( ~lhs ), "Invariant violation detected" );
693 
694  return ~lhs;
695 }
696 //*************************************************************************************************
697 
698 
699 //*************************************************************************************************
711 template< typename MT1 // Type of the left-hand side dense matrix
712  , bool SO1 // Storage order of the left-hand side dense matrix
713  , typename MT2 // Type of the right-hand side dense matrix
714  , bool SO2 > // Storage order of the right-hand side dense matrix
715 inline MT1& operator<<=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs )
716 {
717  return operator<<=( ~lhs, ~rhs );
718 }
719 //*************************************************************************************************
720 
721 
722 //*************************************************************************************************
734 template< typename MT // Type of the dense matrix
735  , bool SO > // Storage order
736 inline MT& operator>>=( DenseMatrix<MT,SO>& mat, int count )
737 {
739 
740  if( IsRestricted_v<MT> ) {
741  if( !tryShift( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), count ) ) {
742  BLAZE_THROW_INVALID_ARGUMENT( "Invalid right-shift of restricted matrix" );
743  }
744  }
745 
746  decltype(auto) left( derestrict( ~mat ) );
747 
748  smpAssign( left, left >> count );
749 
750  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
751 
752  return ~mat;
753 }
754 //*************************************************************************************************
755 
756 
757 //*************************************************************************************************
769 template< typename MT // Type of the dense matrix
770  , bool SO > // Storage order
771 inline MT& operator>>=( DenseMatrix<MT,SO>&& mat, int count )
772 {
773  return operator>>=( ~mat, count );
774 }
775 //*************************************************************************************************
776 
777 
778 //*************************************************************************************************
790 template< typename MT1 // Type of the left-hand side dense matrix
791  , bool SO1 // Storage order of the left-hand side dense matrix
792  , typename MT2 // Type of the right-hand side dense matrix
793  , bool SO2 > // Storage order of the right-hand side dense matrix
795 {
796  if( IsRestricted_v<MT1> ) {
797  if( !tryShiftAssign( ~lhs, ~rhs, 0UL, 0UL ) ) {
798  BLAZE_THROW_INVALID_ARGUMENT( "Invalid right-shift of restricted matrix" );
799  }
800  }
801 
802  decltype(auto) left( derestrict( ~lhs ) );
803 
804  smpAssign( left, left >> (~rhs) );
805 
806  BLAZE_INTERNAL_ASSERT( isIntact( ~lhs ), "Invariant violation detected" );
807 
808  return ~lhs;
809 }
810 //*************************************************************************************************
811 
812 
813 //*************************************************************************************************
825 template< typename MT1 // Type of the left-hand side dense matrix
826  , bool SO1 // Storage order of the left-hand side dense matrix
827  , typename MT2 // Type of the right-hand side dense matrix
828  , bool SO2 > // Storage order of the right-hand side dense matrix
829 inline MT1& operator>>=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs )
830 {
831  return operator>>=( ~lhs, ~rhs );
832 }
833 //*************************************************************************************************
834 
835 
836 //*************************************************************************************************
848 template< typename MT // Type of the left-hand side dense matrix
849  , bool SO // Storage order
850  , typename ST > // Data type of the right-hand side scalar
851 inline auto operator&=( DenseMatrix<MT,SO>& mat, ST scalar )
853 {
855 
856  if( IsRestricted_v<MT> ) {
857  if( !tryBitand( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
858  BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise AND of restricted matrix" );
859  }
860  }
861 
862  decltype(auto) left( derestrict( ~mat ) );
863 
864  smpAssign( left, left & scalar );
865 
866  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
867 
868  return ~mat;
869 }
870 //*************************************************************************************************
871 
872 
873 //*************************************************************************************************
886 template< typename MT // Type of the left-hand side dense matrix
887  , bool SO // Storage order
888  , typename ST > // Data type of the right-hand side scalar
889 inline auto operator&=( DenseMatrix<MT,SO>&& mat, ST scalar )
891 {
892  return operator&=( ~mat, scalar );
893 }
894 //*************************************************************************************************
895 
896 
897 //*************************************************************************************************
909 template< typename MT1 // Type of the left-hand side dense matrix
910  , bool SO1 // Storage order of the left-hand side dense matrix
911  , typename MT2 // Type of the right-hand side dense matrix
912  , bool SO2 > // Storage order of the right-hand side dense matrix
913 inline MT1& operator&=( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
914 {
915  if( IsRestricted_v<MT1> ) {
916  if( !tryBitandAssign( ~lhs, ~rhs, 0UL, 0UL ) ) {
917  BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise AND of restricted matrix" );
918  }
919  }
920 
921  decltype(auto) left( derestrict( ~lhs ) );
922 
923  smpAssign( left, left & (~rhs) );
924 
925  BLAZE_INTERNAL_ASSERT( isIntact( ~lhs ), "Invariant violation detected" );
926 
927  return ~lhs;
928 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
944 template< typename MT1 // Type of the left-hand side dense matrix
945  , bool SO1 // Storage order of the left-hand side dense matrix
946  , typename MT2 // Type of the right-hand side dense matrix
947  , bool SO2 > // Storage order of the right-hand side dense matrix
948 inline MT1& operator&=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs )
949 {
950  return operator&=( ~lhs, ~rhs );
951 }
952 //*************************************************************************************************
953 
954 
955 //*************************************************************************************************
967 template< typename MT // Type of the left-hand side dense matrix
968  , bool SO // Storage order
969  , typename ST > // Data type of the right-hand side scalar
970 inline auto operator|=( DenseMatrix<MT,SO>& mat, ST scalar )
972 {
974 
975  if( IsRestricted_v<MT> ) {
976  if( !tryBitor( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
977  BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise OR of restricted matrix" );
978  }
979  }
980 
981  decltype(auto) left( derestrict( ~mat ) );
982 
983  smpAssign( left, left | scalar );
984 
985  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
986 
987  return ~mat;
988 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1005 template< typename MT // Type of the left-hand side dense matrix
1006  , bool SO // Storage order
1007  , typename ST > // Data type of the right-hand side scalar
1008 inline auto operator|=( DenseMatrix<MT,SO>&& mat, ST scalar )
1009  -> EnableIf_t< IsNumeric_v<ST>, MT& >
1010 {
1011  return operator|=( ~mat, scalar );
1012 }
1013 //*************************************************************************************************
1014 
1015 
1016 //*************************************************************************************************
1028 template< typename MT1 // Type of the left-hand side dense matrix
1029  , bool SO1 // Storage order of the left-hand side dense matrix
1030  , typename MT2 // Type of the right-hand side dense matrix
1031  , bool SO2 > // Storage order of the right-hand side dense matrix
1033 {
1034  if( IsRestricted_v<MT1> ) {
1035  if( !tryBitorAssign( ~lhs, ~rhs, 0UL, 0UL ) ) {
1036  BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise OR of restricted matrix" );
1037  }
1038  }
1039 
1040  decltype(auto) left( derestrict( ~lhs ) );
1041 
1042  smpAssign( left, left | (~rhs) );
1043 
1044  BLAZE_INTERNAL_ASSERT( isIntact( ~lhs ), "Invariant violation detected" );
1045 
1046  return ~lhs;
1047 }
1048 //*************************************************************************************************
1049 
1050 
1051 //*************************************************************************************************
1063 template< typename MT1 // Type of the left-hand side dense matrix
1064  , bool SO1 // Storage order of the left-hand side dense matrix
1065  , typename MT2 // Type of the right-hand side dense matrix
1066  , bool SO2 > // Storage order of the right-hand side dense matrix
1067 inline MT1& operator|=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs )
1068 {
1069  return operator|=( ~lhs, ~rhs );
1070 }
1071 //*************************************************************************************************
1072 
1073 
1074 //*************************************************************************************************
1086 template< typename MT // Type of the left-hand side dense matrix
1087  , bool SO // Storage order
1088  , typename ST > // Data type of the right-hand side scalar
1089 inline auto operator^=( DenseMatrix<MT,SO>& mat, ST scalar )
1090  -> EnableIf_t< IsNumeric_v<ST>, MT& >
1091 {
1093 
1094  if( IsRestricted_v<MT> ) {
1095  if( !tryBitxor( ~mat, 0UL, 0UL, (~mat).rows(), (~mat).columns(), scalar ) ) {
1096  BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise XOR of restricted matrix" );
1097  }
1098  }
1099 
1100  decltype(auto) left( derestrict( ~mat ) );
1101 
1102  smpAssign( left, left ^ scalar );
1103 
1104  BLAZE_INTERNAL_ASSERT( isIntact( ~mat ), "Invariant violation detected" );
1105 
1106  return ~mat;
1107 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1124 template< typename MT // Type of the left-hand side dense matrix
1125  , bool SO // Storage order
1126  , typename ST > // Data type of the right-hand side scalar
1127 inline auto operator^=( DenseMatrix<MT,SO>&& mat, ST scalar )
1128  -> EnableIf_t< IsNumeric_v<ST>, MT& >
1129 {
1130  return operator^=( ~mat, scalar );
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1147 template< typename MT1 // Type of the left-hand side dense matrix
1148  , bool SO1 // Storage order of the left-hand side dense matrix
1149  , typename MT2 // Type of the right-hand side dense matrix
1150  , bool SO2 > // Storage order of the right-hand side dense matrix
1152 {
1153  if( IsRestricted_v<MT1> ) {
1154  if( !tryBitxorAssign( ~lhs, ~rhs, 0UL, 0UL ) ) {
1155  BLAZE_THROW_INVALID_ARGUMENT( "Invalid bitwise XOR of restricted matrix" );
1156  }
1157  }
1158 
1159  decltype(auto) left( derestrict( ~lhs ) );
1160 
1161  smpAssign( left, left ^ (~rhs) );
1162 
1163  BLAZE_INTERNAL_ASSERT( isIntact( ~lhs ), "Invariant violation detected" );
1164 
1165  return ~lhs;
1166 }
1167 //*************************************************************************************************
1168 
1169 
1170 //*************************************************************************************************
1182 template< typename MT1 // Type of the left-hand side dense matrix
1183  , bool SO1 // Storage order of the left-hand side dense matrix
1184  , typename MT2 // Type of the right-hand side dense matrix
1185  , bool SO2 > // Storage order of the right-hand side dense matrix
1186 inline MT1& operator^=( DenseMatrix<MT1,SO1>&& lhs, const DenseMatrix<MT2,SO2>& rhs )
1187 {
1188  return operator^=( ~lhs, ~rhs );
1189 }
1190 //*************************************************************************************************
1191 
1192 
1193 
1194 
1195 //=================================================================================================
1196 //
1197 // GLOBAL FUNCTIONS
1198 //
1199 //=================================================================================================
1200 
1201 //*************************************************************************************************
1204 template< typename MT, bool SO >
1205 bool isnan( const DenseMatrix<MT,SO>& dm );
1206 
1207 template< bool RF, typename MT, bool SO >
1208 bool isSymmetric( const DenseMatrix<MT,SO>& dm );
1209 
1210 template< bool RF, typename MT, bool SO >
1211 bool isHermitian( const DenseMatrix<MT,SO>& dm );
1212 
1213 template< bool RF, typename MT, bool SO >
1214 bool isUniform( const DenseMatrix<MT,SO>& dm );
1215 
1216 template< bool RF, typename MT, bool SO >
1217 bool isZero( const DenseMatrix<MT,SO>& dm );
1218 
1219 template< bool RF, typename MT, bool SO >
1220 bool isLower( const DenseMatrix<MT,SO>& dm );
1221 
1222 template< bool RF, typename MT, bool SO >
1223 bool isUniLower( const DenseMatrix<MT,SO>& dm );
1224 
1225 template< bool RF, typename MT, bool SO >
1226 bool isStrictlyLower( const DenseMatrix<MT,SO>& dm );
1227 
1228 template< bool RF, typename MT, bool SO >
1229 bool isUpper( const DenseMatrix<MT,SO>& dm );
1230 
1231 template< bool RF, typename MT, bool SO >
1232 bool isUniUpper( const DenseMatrix<MT,SO>& dm );
1233 
1234 template< bool RF, typename MT, bool SO >
1235 bool isStrictlyUpper( const DenseMatrix<MT,SO>& dm );
1236 
1237 template< bool RF, typename MT, bool SO >
1238 bool isDiagonal( const DenseMatrix<MT,SO>& dm );
1239 
1240 template< bool RF, typename MT, bool SO >
1241 bool isIdentity( const DenseMatrix<MT,SO>& dm );
1243 //*************************************************************************************************
1244 
1245 
1246 //*************************************************************************************************
1266 template< typename MT // Type of the dense matrix
1267  , bool SO > // Storage order
1268 bool isnan( const DenseMatrix<MT,SO>& dm )
1269 {
1270  using CT = CompositeType_t<MT>;
1271 
1272  CT A( ~dm ); // Evaluation of the dense matrix operand
1273 
1274  if( SO == rowMajor ) {
1275  for( size_t i=0UL; i<A.rows(); ++i ) {
1276  for( size_t j=0UL; j<A.columns(); ++j )
1277  if( isnan( A(i,j) ) ) return true;
1278  }
1279  }
1280  else {
1281  for( size_t j=0UL; j<A.columns(); ++j ) {
1282  for( size_t i=0UL; i<A.rows(); ++i )
1283  if( isnan( A(i,j) ) ) return true;
1284  }
1285  }
1286 
1287  return false;
1288 }
1289 //*************************************************************************************************
1290 
1291 
1292 //*************************************************************************************************
1325 template< bool RF // Relaxation flag
1326  , typename MT // Type of the dense matrix
1327  , bool SO > // Storage order
1329 {
1330  using CT = CompositeType_t<MT>;
1331 
1332  if( IsSymmetric_v<MT> )
1333  return true;
1334 
1335  if( !isSquare( ~dm ) )
1336  return false;
1337 
1338  if( IsUniform_v<MT> || (~dm).rows() < 2UL )
1339  return true;
1340 
1341  if( IsTriangular_v<MT> )
1342  return isDiagonal( ~dm );
1343 
1344  CT A( ~dm ); // Evaluation of the dense matrix operand
1345 
1346  if( SO == rowMajor ) {
1347  for( size_t i=1UL; i<A.rows(); ++i ) {
1348  for( size_t j=0UL; j<i; ++j ) {
1349  if( !equal<RF>( A(i,j), A(j,i) ) )
1350  return false;
1351  }
1352  }
1353  }
1354  else {
1355  for( size_t j=1UL; j<A.columns(); ++j ) {
1356  for( size_t i=0UL; i<j; ++i ) {
1357  if( !equal<RF>( A(i,j), A(j,i) ) )
1358  return false;
1359  }
1360  }
1361  }
1362 
1363  return true;
1364 }
1365 //*************************************************************************************************
1366 
1367 
1368 //*************************************************************************************************
1403 template< bool RF // Relaxation flag
1404  , typename MT // Type of the dense matrix
1405  , bool SO > // Storage order
1407 {
1408  using ET = ElementType_t<MT>;
1409  using CT = CompositeType_t<MT>;
1410 
1411  if( IsHermitian_v<MT> )
1412  return true;
1413 
1414  if( !IsNumeric_v<ET> || !isSquare( ~dm ) )
1415  return false;
1416 
1417  if( IsBuiltin_v<ET> && IsUniform_v<MT> )
1418  return true;
1419 
1420  CT A( ~dm ); // Evaluation of the dense matrix operand
1421 
1422  if( SO == rowMajor ) {
1423  for( size_t i=0UL; i<A.rows(); ++i ) {
1424  for( size_t j=0UL; j<i; ++j ) {
1425  if( !equal<RF>( A(i,j), conj( A(j,i) ) ) )
1426  return false;
1427  }
1428  if( !isReal<RF>( A(i,i) ) )
1429  return false;
1430  }
1431  }
1432  else {
1433  for( size_t j=0UL; j<A.columns(); ++j ) {
1434  for( size_t i=0UL; i<j; ++i ) {
1435  if( !equal<RF>( A(i,j), conj( A(j,i) ) ) )
1436  return false;
1437  }
1438  if( !isReal<RF>( A(j,j) ) )
1439  return false;
1440  }
1441  }
1442 
1443  return true;
1444 }
1445 //*************************************************************************************************
1446 
1447 
1448 //*************************************************************************************************
1456 template< bool RF // Relaxation flag
1457  , typename MT > // Type of the dense matrix
1458 bool isUniform_backend( const DenseMatrix<MT,false>& dm, TrueType )
1459 {
1462 
1463  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
1464  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
1465 
1466  const size_t ibegin( ( IsStrictlyLower_v<MT> )?( 1UL ):( 0UL ) );
1467  const size_t iend ( ( IsStrictlyUpper_v<MT> )?( (~dm).rows()-1UL ):( (~dm).rows() ) );
1468 
1469  for( size_t i=ibegin; i<iend; ++i ) {
1470  if( !IsUpper_v<MT> ) {
1471  for( size_t j=0UL; j<i; ++j ) {
1472  if( !isDefault<RF>( (~dm)(i,j) ) )
1473  return false;
1474  }
1475  }
1476  if( !isDefault<RF>( (~dm)(i,i) ) )
1477  return false;
1478  if( !IsLower_v<MT> ) {
1479  for( size_t j=i+1UL; j<(~dm).columns(); ++j ) {
1480  if( !isDefault<RF>( (~dm)(i,j) ) )
1481  return false;
1482  }
1483  }
1484  }
1485 
1486  return true;
1487 }
1489 //*************************************************************************************************
1490 
1491 
1492 //*************************************************************************************************
1500 template< bool RF // Relaxation flag
1501  , typename MT > // Type of the dense matrix
1502 bool isUniform_backend( const DenseMatrix<MT,true>& dm, TrueType )
1503 {
1506 
1507  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
1508  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
1509 
1510  const size_t jbegin( ( IsStrictlyUpper_v<MT> )?( 1UL ):( 0UL ) );
1511  const size_t jend ( ( IsStrictlyLower_v<MT> )?( (~dm).columns()-1UL ):( (~dm).columns() ) );
1512 
1513  for( size_t j=jbegin; j<jend; ++j ) {
1514  if( !IsLower_v<MT> ) {
1515  for( size_t i=0UL; i<j; ++i ) {
1516  if( !isDefault<RF>( (~dm)(i,j) ) )
1517  return false;
1518  }
1519  }
1520  if( !isDefault<RF>( (~dm)(j,j) ) )
1521  return false;
1522  if( !IsUpper_v<MT> ) {
1523  for( size_t i=j+1UL; i<(~dm).rows(); ++i ) {
1524  if( !isDefault<RF>( (~dm)(i,j) ) )
1525  return false;
1526  }
1527  }
1528  }
1529 
1530  return true;
1531 }
1533 //*************************************************************************************************
1534 
1535 
1536 //*************************************************************************************************
1544 template< bool RF // Relaxation flag
1545  , typename MT > // Type of the dense matrix
1546 bool isUniform_backend( const DenseMatrix<MT,false>& dm, FalseType )
1547 {
1550 
1551  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
1552  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
1553 
1554  const auto& cmp( (~dm)(0UL,0UL) );
1555 
1556  for( size_t i=0UL; i<(~dm).rows(); ++i ) {
1557  for( size_t j=0UL; j<(~dm).columns(); ++j ) {
1558  if( !equal<RF>( (~dm)(i,j), cmp ) )
1559  return false;
1560  }
1561  }
1562 
1563  return true;
1564 }
1566 //*************************************************************************************************
1567 
1568 
1569 //*************************************************************************************************
1577 template< bool RF // Relaxation flag
1578  , typename MT > // Type of the dense matrix
1579 bool isUniform_backend( const DenseMatrix<MT,true>& dm, FalseType )
1580 {
1583 
1584  BLAZE_INTERNAL_ASSERT( (~dm).rows() != 0UL, "Invalid number of rows detected" );
1585  BLAZE_INTERNAL_ASSERT( (~dm).columns() != 0UL, "Invalid number of columns detected" );
1586 
1587  const auto& cmp( (~dm)(0UL,0UL) );
1588 
1589  for( size_t j=0UL; j<(~dm).columns(); ++j ) {
1590  for( size_t i=0UL; i<(~dm).rows(); ++i ) {
1591  if( !equal<RF>( (~dm)(i,j), cmp ) )
1592  return false;
1593  }
1594  }
1595 
1596  return true;
1597 }
1599 //*************************************************************************************************
1600 
1601 
1602 //*************************************************************************************************
1635 template< bool RF // Relaxation flag
1636  , typename MT // Type of the dense matrix
1637  , bool SO > // Storage order
1639 {
1640  if( IsUniform_v<MT> ||
1641  (~dm).rows() == 0UL || (~dm).columns() == 0UL ||
1642  ( (~dm).rows() == 1UL && (~dm).columns() == 1UL ) )
1643  return true;
1644 
1645  if( IsUniTriangular_v<MT> )
1646  return false;
1647 
1648  CompositeType_t<MT> A( ~dm ); // Evaluation of the dense matrix operand
1649 
1650  return isUniform_backend<RF>( A, typename IsTriangular<MT>::Type() );
1651 }
1652 //*************************************************************************************************
1653 
1654 
1655 //*************************************************************************************************
1688 template< bool RF // Relaxation flag
1689  , typename MT // Type of the dense matrix
1690  , bool SO > // Storage order
1691 bool isZero( const DenseMatrix<MT,SO>& dm )
1692 {
1693  const size_t M( (~dm).rows() );
1694  const size_t N( (~dm).columns() );
1695 
1696  if( IsZero_v<MT> || M == 0UL || N == 0UL )
1697  return true;
1698 
1699  if( IsUniTriangular_v<MT> )
1700  return false;
1701 
1702  if( IsUniform_v<MT> )
1703  return isZero<RF>( (~dm)(0UL,0UL) );
1704 
1705  CompositeType_t<MT> A( ~dm ); // Evaluation of the dense matrix operand
1706 
1707  if( SO == rowMajor )
1708  {
1709  for( size_t i=0UL; i<M; ++i )
1710  {
1711  const size_t jbegin( IsUpper_v<MT>
1712  ? ( IsStrictlyUpper_v<MT> ? i+1UL : i )
1713  : 0UL );
1714  const size_t jend ( IsLower_v<MT> || IsSymmetric_v<MT> || IsHermitian_v<MT>
1715  ? ( IsStrictlyLower_v<MT> ? i : i+1UL )
1716  : N );
1717 
1718  for( size_t j=jbegin; j<jend; ++j ) {
1719  if( !isZero<RF>( A(i,j) ) )
1720  return false;
1721  }
1722  }
1723  }
1724  else
1725  {
1726  for( size_t j=0UL; j<N; ++j )
1727  {
1728  const size_t ibegin( IsLower_v<MT>
1729  ? ( IsStrictlyLower_v<MT> ? j+1UL : j )
1730  : 0UL );
1731  const size_t iend ( IsUpper_v<MT> || IsSymmetric_v<MT> || IsHermitian_v<MT>
1732  ? ( IsStrictlyUpper_v<MT> ? j : j+1UL )
1733  : M );
1734 
1735  for( size_t i=ibegin; i<iend; ++i ) {
1736  if( !isZero<RF>( A(i,j) ) )
1737  return false;
1738  }
1739  }
1740  }
1741 
1742  return true;
1743 }
1744 //*************************************************************************************************
1745 
1746 
1747 //*************************************************************************************************
1790 template< bool RF // Relaxation flag
1791  , typename MT // Type of the dense matrix
1792  , bool SO > // Storage order
1793 bool isLower( const DenseMatrix<MT,SO>& dm )
1794 {
1795  using RT = ResultType_t<MT>;
1796  using RN = ReturnType_t<MT>;
1797  using CT = CompositeType_t<MT>;
1798  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1799 
1800  if( IsLower_v<MT> )
1801  return true;
1802 
1803  if( !isSquare( ~dm ) )
1804  return false;
1805 
1806  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1807  return true;
1808 
1809  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1810 
1811  if( IsUniform_v<MT> )
1812  return isDefault<RF>( A(0UL,0UL) );
1813 
1814  if( SO == rowMajor ) {
1815  for( size_t i=0UL; i<A.rows()-1UL; ++i ) {
1816  for( size_t j=i+1UL; j<A.columns(); ++j ) {
1817  if( !isDefault<RF>( A(i,j) ) )
1818  return false;
1819  }
1820  }
1821  }
1822  else {
1823  for( size_t j=1UL; j<A.columns(); ++j ) {
1824  for( size_t i=0UL; i<j; ++i ) {
1825  if( !isDefault<RF>( A(i,j) ) )
1826  return false;
1827  }
1828  }
1829  }
1830 
1831  return true;
1832 }
1833 //*************************************************************************************************
1834 
1835 
1836 //*************************************************************************************************
1878 template< bool RF // Relaxation flag
1879  , typename MT // Type of the dense matrix
1880  , bool SO > // Storage order
1882 {
1883  using RT = ResultType_t<MT>;
1884  using RN = ReturnType_t<MT>;
1885  using CT = CompositeType_t<MT>;
1886  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1887 
1888  if( IsUniLower_v<MT> )
1889  return true;
1890 
1891  if( !isSquare( ~dm ) )
1892  return false;
1893 
1894  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1895 
1896  if( SO == rowMajor ) {
1897  for( size_t i=0UL; i<A.rows(); ++i ) {
1898  if( !isOne<RF>( A(i,i) ) )
1899  return false;
1900  for( size_t j=i+1UL; j<A.columns(); ++j ) {
1901  if( !isZero<RF>( A(i,j) ) )
1902  return false;
1903  }
1904  }
1905  }
1906  else {
1907  for( size_t j=0UL; j<A.columns(); ++j ) {
1908  for( size_t i=0UL; i<j; ++i ) {
1909  if( !isZero<RF>( A(i,j) ) )
1910  return false;
1911  }
1912  if( !isOne<RF>( A(j,j) ) )
1913  return false;
1914  }
1915  }
1916 
1917  return true;
1918 }
1919 //*************************************************************************************************
1920 
1921 
1922 //*************************************************************************************************
1965 template< bool RF // Relaxation flag
1966  , typename MT // Type of the dense matrix
1967  , bool SO > // Storage order
1969 {
1970  using RT = ResultType_t<MT>;
1971  using RN = ReturnType_t<MT>;
1972  using CT = CompositeType_t<MT>;
1973  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
1974 
1975  if( IsStrictlyLower_v<MT> )
1976  return true;
1977 
1978  if( !isSquare( ~dm ) )
1979  return false;
1980 
1981  if( IsZero_v<MT> || (~dm).rows() < 2UL )
1982  return true;
1983 
1984  if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
1985  return false;
1986 
1987  Tmp A( ~dm ); // Evaluation of the dense matrix operand
1988 
1989  if( IsUniform_v<MT> )
1990  return isDefault<RF>( A(0UL,0UL) );
1991 
1992  if( SO == rowMajor ) {
1993  for( size_t i=0UL; i<A.rows(); ++i ) {
1994  for( size_t j=i; j<A.columns(); ++j ) {
1995  if( !isDefault<RF>( A(i,j) ) )
1996  return false;
1997  }
1998  }
1999  }
2000  else {
2001  for( size_t j=0UL; j<A.columns(); ++j ) {
2002  for( size_t i=0UL; i<=j; ++i ) {
2003  if( !isDefault<RF>( A(i,j) ) )
2004  return false;
2005  }
2006  }
2007  }
2008 
2009  return true;
2010 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2057 template< bool RF // Relaxation flag
2058  , typename MT // Type of the dense matrix
2059  , bool SO > // Storage order
2060 bool isUpper( const DenseMatrix<MT,SO>& dm )
2061 {
2062  using RT = ResultType_t<MT>;
2063  using RN = ReturnType_t<MT>;
2064  using CT = CompositeType_t<MT>;
2065  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2066 
2067  if( IsUpper_v<MT> )
2068  return true;
2069 
2070  if( !isSquare( ~dm ) )
2071  return false;
2072 
2073  if( IsZero_v<MT> || (~dm).rows() < 2UL )
2074  return true;
2075 
2076  Tmp A( ~dm ); // Evaluation of the dense matrix operand
2077 
2078  if( IsUniform_v<MT> )
2079  return isDefault<RF>( A(0UL,0UL) );
2080 
2081  if( SO == rowMajor ) {
2082  for( size_t i=1UL; i<A.rows(); ++i ) {
2083  for( size_t j=0UL; j<i; ++j ) {
2084  if( !isDefault<RF>( A(i,j) ) )
2085  return false;
2086  }
2087  }
2088  }
2089  else {
2090  for( size_t j=0UL; j<A.columns()-1UL; ++j ) {
2091  for( size_t i=j+1UL; i<A.rows(); ++i ) {
2092  if( !isDefault<RF>( A(i,j) ) )
2093  return false;
2094  }
2095  }
2096  }
2097 
2098  return true;
2099 }
2100 //*************************************************************************************************
2101 
2102 
2103 //*************************************************************************************************
2145 template< bool RF // Relaxation flag
2146  , typename MT // Type of the dense matrix
2147  , bool SO > // Storage order
2149 {
2150  using RT = ResultType_t<MT>;
2151  using RN = ReturnType_t<MT>;
2152  using CT = CompositeType_t<MT>;
2153  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2154 
2155  if( IsUniUpper_v<MT> )
2156  return true;
2157 
2158  if( !isSquare( ~dm ) )
2159  return false;
2160 
2161  Tmp A( ~dm ); // Evaluation of the dense matrix operand
2162 
2163  if( SO == rowMajor ) {
2164  for( size_t i=0UL; i<A.rows(); ++i ) {
2165  for( size_t j=0UL; j<i; ++j ) {
2166  if( !isZero<RF>( A(i,j) ) )
2167  return false;
2168  }
2169  if( !isOne<RF>( A(i,i) ) )
2170  return false;
2171  }
2172  }
2173  else {
2174  for( size_t j=0UL; j<A.columns(); ++j ) {
2175  if( !isOne<RF>( A(j,j) ) )
2176  return false;
2177  for( size_t i=j+1UL; i<A.rows(); ++i ) {
2178  if( !isZero<RF>( A(i,j) ) )
2179  return false;
2180  }
2181  }
2182  }
2183 
2184  return true;
2185 }
2186 //*************************************************************************************************
2187 
2188 
2189 //*************************************************************************************************
2232 template< bool RF // Relaxation flag
2233  , typename MT // Type of the dense matrix
2234  , bool SO > // Storage order
2236 {
2237  using RT = ResultType_t<MT>;
2238  using RN = ReturnType_t<MT>;
2239  using CT = CompositeType_t<MT>;
2240  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2241 
2242  if( IsStrictlyUpper_v<MT> )
2243  return true;
2244 
2245  if( !isSquare( ~dm ) )
2246  return false;
2247 
2248  if( IsZero_v<MT> || (~dm).rows() < 2UL )
2249  return true;
2250 
2251  if( IsUniLower_v<MT> || IsUniUpper_v<MT> )
2252  return false;
2253 
2254  Tmp A( ~dm ); // Evaluation of the dense matrix operand
2255 
2256  if( IsUniform_v<MT> )
2257  return isDefault<RF>( A(0UL,0UL) );
2258 
2259  if( SO == rowMajor ) {
2260  for( size_t i=0UL; i<A.rows(); ++i ) {
2261  for( size_t j=0UL; j<=i; ++j ) {
2262  if( !isDefault<RF>( A(i,j) ) )
2263  return false;
2264  }
2265  }
2266  }
2267  else {
2268  for( size_t j=0UL; j<A.columns(); ++j ) {
2269  for( size_t i=j; i<A.rows(); ++i ) {
2270  if( !isDefault<RF>( A(i,j) ) )
2271  return false;
2272  }
2273  }
2274  }
2275 
2276  return true;
2277 }
2278 //*************************************************************************************************
2279 
2280 
2281 //*************************************************************************************************
2325 template< bool RF // Relaxation flag
2326  , typename MT // Type of the dense matrix
2327  , bool SO > // Storage order
2329 {
2330  using RT = ResultType_t<MT>;
2331  using RN = ReturnType_t<MT>;
2332  using CT = CompositeType_t<MT>;
2333  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2334 
2335  if( IsDiagonal_v<MT> )
2336  return true;
2337 
2338  if( !isSquare( ~dm ) )
2339  return false;
2340 
2341  if( IsZero_v<MT> || (~dm).rows() < 2UL )
2342  return true;
2343 
2344  Tmp A( ~dm ); // Evaluation of the dense matrix operand
2345 
2346  if( IsUniform_v<MT> )
2347  return isDefault<RF>( A(0UL,0UL) );
2348 
2349  if( SO == rowMajor ) {
2350  for( size_t i=0UL; i<A.rows(); ++i ) {
2351  if( !IsUpper_v<MT> ) {
2352  for( size_t j=0UL; j<i; ++j ) {
2353  if( !isDefault<RF>( A(i,j) ) )
2354  return false;
2355  }
2356  }
2357  if( !IsLower_v<MT> ) {
2358  for( size_t j=i+1UL; j<A.columns(); ++j ) {
2359  if( !isDefault<RF>( A(i,j) ) )
2360  return false;
2361  }
2362  }
2363  }
2364  }
2365  else {
2366  for( size_t j=0UL; j<A.columns(); ++j ) {
2367  if( !IsLower_v<MT> ) {
2368  for( size_t i=0UL; i<j; ++i ) {
2369  if( !isDefault<RF>( A(i,j) ) )
2370  return false;
2371  }
2372  }
2373  if( !IsUpper_v<MT> ) {
2374  for( size_t i=j+1UL; i<A.rows(); ++i ) {
2375  if( !isDefault<RF>( A(i,j) ) )
2376  return false;
2377  }
2378  }
2379  }
2380  }
2381 
2382  return true;
2383 }
2384 //*************************************************************************************************
2385 
2386 
2387 //*************************************************************************************************
2430 template< bool RF // Relaxation flag
2431  , typename MT // Type of the dense matrix
2432  , bool SO > // Storage order
2434 {
2435  using RT = ResultType_t<MT>;
2436  using RN = ReturnType_t<MT>;
2437  using CT = CompositeType_t<MT>;
2438  using Tmp = If_t< IsExpression_v<RN>, const RT, CT >;
2439 
2440  if( IsIdentity_v<MT> )
2441  return true;
2442 
2443  if( !isSquare( ~dm ) )
2444  return false;
2445 
2446  if( (~dm).rows() == 0UL )
2447  return true;
2448 
2449  Tmp A( ~dm ); // Evaluation of the dense matrix operand
2450 
2451  if( SO == rowMajor ) {
2452  for( size_t i=0UL; i<A.rows(); ++i ) {
2453  if( !IsUpper_v<MT> ) {
2454  for( size_t j=0UL; j<i; ++j ) {
2455  if( !isZero<RF>( A(i,j) ) )
2456  return false;
2457  }
2458  }
2459  if( !IsUniLower_v<MT> && !IsUniUpper_v<MT> && !isOne<RF>( A(i,i) ) ) {
2460  return false;
2461  }
2462  if( !IsLower_v<MT> ) {
2463  for( size_t j=i+1UL; j<A.columns(); ++j ) {
2464  if( !isZero<RF>( A(i,j) ) )
2465  return false;
2466  }
2467  }
2468  }
2469  }
2470  else {
2471  for( size_t j=0UL; j<A.columns(); ++j ) {
2472  if( !IsLower_v<MT> ) {
2473  for( size_t i=0UL; i<j; ++i ) {
2474  if( !isZero<RF>( A(i,j) ) )
2475  return false;
2476  }
2477  }
2478  if( !IsUniLower_v<MT> && !IsUniUpper_v<MT> && !isOne<RF>( A(j,j) ) ) {
2479  return false;
2480  }
2481  if( !IsUpper_v<MT> ) {
2482  for( size_t i=j+1UL; i<A.rows(); ++i ) {
2483  if( !isZero<RF>( A(i,j) ) )
2484  return false;
2485  }
2486  }
2487  }
2488  }
2489 
2490  return true;
2491 }
2492 //*************************************************************************************************
2493 
2494 } // namespace blaze
2495 
2496 #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: IntegralConstant.h:121
#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.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1793
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:2060
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1968
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
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 template for the If class template.The If_t alias template provides a convenient shor...
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 isZero shim.
Header file for the IsDiagonal type trait.
auto operator^=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Bitwise XOR assignment operator for the bitwise XOR of a dense matrix and a scalar value.
Definition: DenseMatrix.h:1089
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1881
#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:2328
auto operator&=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Bitwise AND assignment operator for the bitwise AND of a dense matrix and a scalar value.
Definition: DenseMatrix.h:851
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
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:81
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:2433
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:677
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.
MT & operator<<=(DenseMatrix< MT, SO > &mat, int count)
Left-shift assignment operator for the uniform left-shift of a dense matrix.
Definition: DenseMatrix.h:622
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.
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
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:717
bool isUniform(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a uniform matrix.
Definition: DenseMatrix.h:1638
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.
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:558
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:2235
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:1406
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:1328
#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
auto operator|=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Bitwise OR assignment operator for the bitwise OR of a dense matrix and a scalar value.
Definition: DenseMatrix.h:970
Header file for the IsBuiltin type trait.
Header file for the IntegralConstant class template.
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:2148
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
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:494
Header file for the IsUpper type trait.
MT & operator>>=(DenseMatrix< MT, SO > &mat, int count)
Right-shift assignment operator for the uniform right-shift of a dense matrix.
Definition: DenseMatrix.h:736
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1324
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,...
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 IsExpression type trait class.