Submatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SUBMATRIX_H_
36 #define _BLAZE_MATH_VIEWS_SUBMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
84 #include <blaze/math/views/Check.h>
93 #include <blaze/util/Assert.h>
95 #include <blaze/util/DisableIf.h>
99 #include <blaze/util/SmallArray.h>
100 #include <blaze/util/StaticAssert.h>
101 #include <blaze/util/TrueType.h>
102 #include <blaze/util/TypeList.h>
103 #include <blaze/util/Types.h>
105 #include <blaze/util/Unused.h>
106 
107 
108 namespace blaze {
109 
110 //=================================================================================================
111 //
112 // GLOBAL FUNCTIONS
113 //
114 //=================================================================================================
115 
116 //*************************************************************************************************
170 template< size_t I // Index of the first row
171  , size_t J // Index of the first column
172  , size_t M // Number of rows
173  , size_t N // Number of columns
174  , typename MT // Type of the dense matrix
175  , bool SO // Storage order
176  , typename... RSAs > // Optional submatrix arguments
177 inline decltype(auto) submatrix( Matrix<MT,SO>& matrix, RSAs... args )
178 {
180 
181  return submatrix<unaligned,I,J,M,N>( ~matrix, args... );
182 }
183 //*************************************************************************************************
184 
185 
186 //*************************************************************************************************
239 template< size_t I // Index of the first row
240  , size_t J // Index of the first column
241  , size_t M // Number of rows
242  , size_t N // Number of columns
243  , typename MT // Type of the dense matrix
244  , bool SO // Storage order
245  , typename... RSAs > // Option submatrix arguments
246 inline decltype(auto) submatrix( const Matrix<MT,SO>& matrix, RSAs... args )
247 {
249 
250  return submatrix<unaligned,I,J,M,N>( ~matrix, args... );
251 }
252 //*************************************************************************************************
253 
254 
255 //*************************************************************************************************
270 template< size_t I // Index of the first row
271  , size_t J // Index of the first column
272  , size_t M // Number of rows
273  , size_t N // Number of columns
274  , typename MT // Type of the dense matrix
275  , bool SO // Storage order
276  , typename... RSAs > // Option submatrix arguments
277 inline decltype(auto) submatrix( Matrix<MT,SO>&& matrix, RSAs... args )
278 {
280 
281  return submatrix<unaligned,I,J,M,N>( ~matrix, args... );
282 }
283 //*************************************************************************************************
284 
285 
286 //*************************************************************************************************
352 template< AlignmentFlag AF // Alignment flag
353  , size_t I // Index of the first row
354  , size_t J // Index of the first column
355  , size_t M // Number of rows
356  , size_t N // Number of columns
357  , typename MT // Type of the dense matrix
358  , bool SO // Storage order
359  , typename... RSAs > // Option submatrix arguments
360 inline decltype(auto) submatrix( Matrix<MT,SO>& matrix, RSAs... args )
361 {
363 
364  using ReturnType = Submatrix_<MT,AF,I,J,M,N>;
365  return ReturnType( ~matrix, args... );
366 }
367 //*************************************************************************************************
368 
369 
370 //*************************************************************************************************
434 template< AlignmentFlag AF // Alignment flag
435  , size_t I // Index of the first row
436  , size_t J // Index of the first column
437  , size_t M // Number of rows
438  , size_t N // Number of columns
439  , typename MT // Type of the dense matrix
440  , bool SO // Storage order
441  , typename... RSAs > // Option submatrix arguments
442 inline decltype(auto) submatrix( const Matrix<MT,SO>& matrix, RSAs... args )
443 {
445 
446  using ReturnType = const Submatrix_<const MT,AF,I,J,M,N>;
447  return ReturnType( ~matrix, args... );
448 }
449 //*************************************************************************************************
450 
451 
452 //*************************************************************************************************
468 template< AlignmentFlag AF // Alignment flag
469  , size_t I // Index of the first row
470  , size_t J // Index of the first column
471  , size_t M // Number of rows
472  , size_t N // Number of columns
473  , typename MT // Type of the dense matrix
474  , bool SO // Storage order
475  , typename... RSAs > // Option submatrix arguments
476 inline decltype(auto) submatrix( Matrix<MT,SO>&& matrix, RSAs... args )
477 {
479 
480  using ReturnType = Submatrix_<MT,AF,I,J,M,N>;
481  return ReturnType( ~matrix, args... );
482 }
483 //*************************************************************************************************
484 
485 
486 //*************************************************************************************************
544 template< typename MT // Type of the dense matrix
545  , bool SO // Storage order
546  , typename... RSAs > // Option submatrix arguments
547 inline decltype(auto)
548  submatrix( Matrix<MT,SO>& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
549 {
551 
552  return submatrix<unaligned>( ~matrix, row, column, m, n, args... );
553 }
554 //*************************************************************************************************
555 
556 
557 //*************************************************************************************************
614 template< typename MT // Type of the dense matrix
615  , bool SO // Storage order
616  , typename... RSAs > // Option submatrix arguments
617 inline decltype(auto)
618  submatrix( const Matrix<MT,SO>& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
619 {
621 
622  return submatrix<unaligned>( ~matrix, row, column, m, n, args... );
623 }
624 //*************************************************************************************************
625 
626 
627 //*************************************************************************************************
646 template< typename MT // Type of the dense matrix
647  , bool SO // Storage order
648  , typename... RSAs > // Option submatrix arguments
649 inline decltype(auto)
650  submatrix( Matrix<MT,SO>&& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
651 {
653 
654  return submatrix<unaligned>( ~matrix, row, column, m, n, args... );
655 }
656 //*************************************************************************************************
657 
658 
659 //*************************************************************************************************
729 template< AlignmentFlag AF // Alignment flag
730  , typename MT // Type of the dense matrix
731  , bool SO // Storage order
732  , typename... RSAs > // Option submatrix arguments
733 inline decltype(auto)
734  submatrix( Matrix<MT,SO>& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
735 {
737 
738  using ReturnType = Submatrix_<MT,AF>;
739  return ReturnType( ~matrix, row, column, m, n, args... );
740 }
741 //*************************************************************************************************
742 
743 
744 //*************************************************************************************************
812 template< AlignmentFlag AF // Alignment flag
813  , typename MT // Type of the dense matrix
814  , bool SO // Storage order
815  , typename... RSAs > // Option submatrix arguments
816 inline decltype(auto)
817  submatrix( const Matrix<MT,SO>& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
818 {
820 
821  using ReturnType = const Submatrix_<const MT,AF>;
822  return ReturnType( ~matrix, row, column, m, n, args... );
823 }
824 //*************************************************************************************************
825 
826 
827 //*************************************************************************************************
847 template< AlignmentFlag AF // Alignment flag
848  , typename MT // Type of the dense matrix
849  , bool SO // Storage order
850  , typename... RSAs > // Option submatrix arguments
851 inline decltype(auto)
852  submatrix( Matrix<MT,SO>&& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
853 {
855 
856  using ReturnType = Submatrix_<MT,AF>;
857  return ReturnType( ~matrix, row, column, m, n, args... );
858 }
859 //*************************************************************************************************
860 
861 
862 
863 
864 //=================================================================================================
865 //
866 // GLOBAL RESTRUCTURING FUNCTIONS
867 //
868 //=================================================================================================
869 
870 //*************************************************************************************************
882 template< AlignmentFlag AF // Alignment flag
883  , size_t... CSAs // Compile time submatrix arguments
884  , typename MT // Matrix base type of the expression
885  , typename... RSAs > // Runtime submatrix arguments
886 inline decltype(auto) submatrix( const MatMatAddExpr<MT>& matrix, RSAs... args )
887 {
889 
890  return submatrix<AF,CSAs...>( (~matrix).leftOperand(), args... ) +
891  submatrix<AF,CSAs...>( (~matrix).rightOperand(), args... );
892 }
894 //*************************************************************************************************
895 
896 
897 //*************************************************************************************************
909 template< AlignmentFlag AF // Alignment flag
910  , size_t... CSAs // Compile time submatrix arguments
911  , typename MT // Matrix base type of the expression
912  , typename... RSAs > // Runtime submatrix arguments
913 inline decltype(auto) submatrix( const MatMatSubExpr<MT>& matrix, RSAs... args )
914 {
916 
917  return submatrix<AF,CSAs...>( (~matrix).leftOperand(), args... ) -
918  submatrix<AF,CSAs...>( (~matrix).rightOperand(), args... );
919 }
921 //*************************************************************************************************
922 
923 
924 //*************************************************************************************************
936 template< AlignmentFlag AF // Alignment flag
937  , size_t... CSAs // Compile time submatrix arguments
938  , typename MT // Matrix base type of the expression
939  , typename... RSAs > // Runtime submatrix arguments
940 inline decltype(auto) submatrix( const SchurExpr<MT>& matrix, RSAs... args )
941 {
943 
944  return submatrix<AF,CSAs...>( (~matrix).leftOperand(), args... ) %
945  submatrix<AF,CSAs...>( (~matrix).rightOperand(), args... );
946 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
963 template< AlignmentFlag AF // Alignment flag
964  , size_t... CSAs // Compile time submatrix arguments
965  , typename MT // Matrix base type of the expression
966  , typename... RSAs > // Runtime submatrix arguments
967 inline decltype(auto) submatrix( const MatMatMultExpr<MT>& matrix, RSAs... args )
968 {
970 
971  using MT1 = RemoveReference_t< LeftOperand_t< MatrixType_t<MT> > >;
972  using MT2 = RemoveReference_t< RightOperand_t< MatrixType_t<MT> > >;
973 
974  const SubmatrixData<CSAs...> sd( args... );
975 
976  BLAZE_DECLTYPE_AUTO( left , (~matrix).leftOperand() );
977  BLAZE_DECLTYPE_AUTO( right, (~matrix).rightOperand() );
978 
979  const size_t begin( max( ( IsUpper_v<MT1> )
980  ?( ( !AF && IsStrictlyUpper_v<MT1> )
981  ?( sd.row() + 1UL )
982  :( sd.row() ) )
983  :( 0UL )
984  , ( IsLower_v<MT2> )
985  ?( ( !AF && IsStrictlyLower_v<MT2> )
986  ?( sd.column() + 1UL )
987  :( sd.column() ) )
988  :( 0UL ) ) );
989  const size_t end( min( ( IsLower_v<MT1> )
990  ?( ( IsStrictlyLower_v<MT1> && sd.rows() > 0UL )
991  ?( sd.row() + sd.rows() - 1UL )
992  :( sd.row() + sd.rows() ) )
993  :( left.columns() )
994  , ( IsUpper_v<MT2> )
995  ?( ( IsStrictlyUpper_v<MT2> && sd.columns() > 0UL )
996  ?( sd.column() + sd.columns() - 1UL )
997  :( sd.column() + sd.columns() ) )
998  :( left.columns() ) ) );
999 
1000  const size_t diff( ( begin < end )?( end - begin ):( 0UL ) );
1001 
1002  return submatrix<AF>( left, sd.row(), begin, sd.rows(), diff ) *
1003  submatrix<AF>( right, begin, sd.column(), diff, sd.columns() );
1004 }
1006 //*************************************************************************************************
1007 
1008 
1009 //*************************************************************************************************
1020 template< AlignmentFlag AF // Alignment flag
1021  , size_t I // Index of the first row
1022  , size_t J // Index of the first column
1023  , size_t M // Number of rows
1024  , size_t N // Number of columns
1025  , typename MT // Matrix base type of the expression
1026  , typename... RSAs > // Runtime submatrix arguments
1027 inline decltype(auto) submatrix( const VecTVecMultExpr<MT>& matrix, RSAs... args )
1028 {
1030 
1031  return subvector<AF,I,M>( (~matrix).leftOperand(), args... ) *
1032  subvector<AF,J,N>( (~matrix).rightOperand(), args... );
1033 }
1035 //*************************************************************************************************
1036 
1037 
1038 //*************************************************************************************************
1053 template< AlignmentFlag AF // Alignment flag
1054  , typename MT // Matrix base type of the expression
1055  , typename... RSAs > // Runtime submatrix arguments
1056 inline decltype(auto)
1057  submatrix( const VecTVecMultExpr<MT>& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
1058 {
1060 
1061  return subvector<AF>( (~matrix).leftOperand(), row, m, args... ) *
1062  subvector<AF>( (~matrix).rightOperand(), column, n, args... );
1063 }
1065 //*************************************************************************************************
1066 
1067 
1068 //*************************************************************************************************
1080 template< AlignmentFlag AF // Alignment flag
1081  , size_t... CSAs // Compile time submatrix arguments
1082  , typename MT // Matrix base type of the expression
1083  , typename... RSAs > // Runtime submatrix arguments
1084 inline decltype(auto) submatrix( const MatScalarMultExpr<MT>& matrix, RSAs... args )
1085 {
1087 
1088  return submatrix<AF,CSAs...>( (~matrix).leftOperand(), args... ) * (~matrix).rightOperand();
1089 }
1091 //*************************************************************************************************
1092 
1093 
1094 //*************************************************************************************************
1106 template< AlignmentFlag AF // Alignment flag
1107  , size_t... CSAs // Compile time submatrix arguments
1108  , typename MT // Matrix base type of the expression
1109  , typename... RSAs > // Runtime submatrix arguments
1110 inline decltype(auto) submatrix( const MatScalarDivExpr<MT>& matrix, RSAs... args )
1111 {
1113 
1114  return submatrix<AF,CSAs...>( (~matrix).leftOperand(), args... ) / (~matrix).rightOperand();
1115 }
1117 //*************************************************************************************************
1118 
1119 
1120 //*************************************************************************************************
1132 template< AlignmentFlag AF // Alignment flag
1133  , size_t... CSAs // Compile time submatrix arguments
1134  , typename MT // Matrix base type of the expression
1135  , typename... RSAs > // Runtime submatrix arguments
1136 inline decltype(auto) submatrix( const MatMapExpr<MT>& matrix, RSAs... args )
1137 {
1139 
1140  return map( submatrix<AF,CSAs...>( (~matrix).operand(), args... ), (~matrix).operation() );
1141 }
1143 //*************************************************************************************************
1144 
1145 
1146 //*************************************************************************************************
1158 template< AlignmentFlag AF // Alignment flag
1159  , size_t... CSAs // Compile time submatrix arguments
1160  , typename MT // Matrix base type of the expression
1161  , typename... RSAs > // Runtime submatrix arguments
1162 inline decltype(auto) submatrix( const MatMatMapExpr<MT>& matrix, RSAs... args )
1163 {
1165 
1166  return map( submatrix<AF,CSAs...>( (~matrix).leftOperand(), args... ),
1167  submatrix<AF,CSAs...>( (~matrix).rightOperand(), args... ),
1168  (~matrix).operation() );
1169 }
1171 //*************************************************************************************************
1172 
1173 
1174 //*************************************************************************************************
1186 template< AlignmentFlag AF // Alignment flag
1187  , size_t... CSAs // Compile time submatrix arguments
1188  , typename MT // Matrix base type of the expression
1189  , typename... RSAs > // Runtime submatrix arguments
1190 inline decltype(auto) submatrix( const MatEvalExpr<MT>& matrix, RSAs... args )
1191 {
1193 
1194  return eval( submatrix<AF,CSAs...>( (~matrix).operand(), args... ) );
1195 }
1197 //*************************************************************************************************
1198 
1199 
1200 //*************************************************************************************************
1212 template< AlignmentFlag AF // Alignment flag
1213  , size_t... CSAs // Compile time submatrix arguments
1214  , typename MT // Matrix base type of the expression
1215  , typename... RSAs > // Runtime submatrix arguments
1216 inline decltype(auto) submatrix( const MatSerialExpr<MT>& matrix, RSAs... args )
1217 {
1219 
1220  return serial( submatrix<AF,CSAs...>( (~matrix).operand(), args... ) );
1221 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1238 template< AlignmentFlag AF // Alignment flag
1239  , size_t... CSAs // Compile time submatrix arguments
1240  , typename MT // Matrix base type of the expression
1241  , typename... RSAs > // Runtime submatrix arguments
1242 inline decltype(auto) submatrix( const DeclExpr<MT>& matrix, RSAs... args )
1243 {
1245 
1246  return submatrix<AF,CSAs...>( (~matrix).operand(), args... );
1247 }
1249 //*************************************************************************************************
1250 
1251 
1252 //*************************************************************************************************
1264 template< AlignmentFlag AF // Alignment flag
1265  , size_t I // Index of the first row
1266  , size_t J // Index of the first column
1267  , size_t M // Number of rows
1268  , size_t N // Number of columns
1269  , typename MT // Matrix base type of the expression
1270  , typename... RSAs > // Optional submatrix arguments
1271 inline decltype(auto) submatrix( const MatTransExpr<MT>& matrix, RSAs... args )
1272 {
1274 
1275  return trans( submatrix<AF,J,I,N,M>( (~matrix).operand(), args... ) );
1276 }
1278 //*************************************************************************************************
1279 
1280 
1281 //*************************************************************************************************
1297 template< AlignmentFlag AF // Alignment flag
1298  , typename MT // Matrix base type of the expression
1299  , typename... RSAs > // Optional submatrix arguments
1300 inline decltype(auto)
1301  submatrix( const MatTransExpr<MT>& matrix, size_t row, size_t column, size_t m, size_t n, RSAs... args )
1302 {
1304 
1305  return trans( submatrix<AF>( (~matrix).operand(), column, row, n, m, args... ) );
1306 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1323 template< AlignmentFlag AF // Alignment flag
1324  , size_t I // Index of the first row
1325  , size_t J // Index of the first column
1326  , size_t M // Number of rows
1327  , size_t N // Number of columns
1328  , typename MT // Matrix base type of the expression
1329  , size_t... CEAs // Compile time expansion arguments
1330  , typename... RSAs > // Optional submatrix arguments
1331 inline decltype(auto) submatrix( const VecExpandExpr<MT,CEAs...>& matrix, RSAs... args )
1332 {
1334 
1335  using VT = VectorType_t< RemoveReference_t< decltype( (~matrix).operand() ) > >;
1336 
1337  constexpr bool TF( TransposeFlag_v<VT> );
1338 
1339  constexpr size_t index ( TF ? J : I );
1340  constexpr size_t size ( TF ? N : M );
1341  constexpr size_t expansion( TF ? M : N );
1342 
1343  return expand<expansion>( subvector<index,size>( (~matrix).operand(), args... ) );
1344 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1365 template< AlignmentFlag AF // Alignment flag
1366  , typename MT // Matrix base type of the expression
1367  , size_t... CEAs // Compile time expansion arguments
1368  , typename... RSAs > // Optional submatrix arguments
1369 inline decltype(auto)
1370  submatrix( const VecExpandExpr<MT,CEAs...>& matrix,
1371  size_t row, size_t column, size_t m, size_t n, RSAs... args )
1372 {
1374 
1375  using VT = VectorType_t< RemoveReference_t< decltype( (~matrix).operand() ) > >;
1376 
1377  constexpr bool TF( TransposeFlag_v<VT> );
1378 
1379  const size_t index ( TF ? column : row );
1380  const size_t size ( TF ? n : m );
1381  const size_t expansion( TF ? m : n );
1382 
1383  return expand( subvector( (~matrix).operand(), index, size, args... ), expansion );
1384 }
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1400 template< AlignmentFlag AF1 // Required alignment flag
1401  , size_t I1 // Required index of the first row
1402  , size_t J1 // Required index of the first column
1403  , size_t M1 // Required number of rows
1404  , size_t N1 // Required number of columns
1405  , typename MT // Type of the sparse submatrix
1406  , AlignmentFlag AF2 // Present alignment flag
1407  , bool SO // Storage order
1408  , bool DF // Density flag
1409  , size_t I2 // Present index of the first row
1410  , size_t J2 // Present index of the first column
1411  , size_t M2 // Present number of rows
1412  , size_t N2 // Present number of columns
1413  , typename... RSAs > // Optional submatrix arguments
1414 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF,I2,J2,M2,N2>& sm, RSAs... args )
1415 {
1417 
1418  BLAZE_STATIC_ASSERT_MSG( I1 + M1 <= M2, "Invalid submatrix specification" );
1419  BLAZE_STATIC_ASSERT_MSG( J1 + N1 <= N2, "Invalid submatrix specification" );
1420 
1421  return submatrix<AF1,I1+I2,J1+J2,M1,N1>( sm.operand(), args... );
1422 }
1424 //*************************************************************************************************
1425 
1426 
1427 //*************************************************************************************************
1439 template< AlignmentFlag AF1 // Required alignment flag
1440  , size_t I1 // Required index of the first row
1441  , size_t J1 // Required index of the first column
1442  , size_t M1 // Required number of rows
1443  , size_t N1 // Required number of columns
1444  , typename MT // Type of the sparse submatrix
1445  , AlignmentFlag AF2 // Present alignment flag
1446  , bool SO // Storage order
1447  , bool DF // Density flag
1448  , size_t I2 // Present index of the first row
1449  , size_t J2 // Present index of the first column
1450  , size_t M2 // Present number of rows
1451  , size_t N2 // Present number of columns
1452  , typename... RSAs > // Optional submatrix arguments
1453 inline decltype(auto) submatrix( const Submatrix<MT,AF2,SO,DF,I2,J2,M2,N2>& sm, RSAs... args )
1454 {
1456 
1457  BLAZE_STATIC_ASSERT_MSG( I1 + M1 <= M2, "Invalid submatrix specification" );
1458  BLAZE_STATIC_ASSERT_MSG( J1 + N1 <= N2, "Invalid submatrix specification" );
1459 
1460  return submatrix<AF1,I1+I2,J1+J2,M1,N1>( sm.operand(), args... );
1461 }
1463 //*************************************************************************************************
1464 
1465 
1466 //*************************************************************************************************
1478 template< AlignmentFlag AF1 // Required alignment flag
1479  , size_t I1 // Required index of the first row
1480  , size_t J1 // Required index of the first column
1481  , size_t M1 // Required number of rows
1482  , size_t N1 // Required number of columns
1483  , typename MT // Type of the sparse submatrix
1484  , AlignmentFlag AF2 // Present alignment flag
1485  , bool SO // Storage order
1486  , bool DF // Density flag
1487  , size_t I2 // Present index of the first row
1488  , size_t J2 // Present index of the first column
1489  , size_t M2 // Present number of rows
1490  , size_t N2 // Present number of columns
1491  , typename... RSAs > // Optional submatrix arguments
1492 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF,I2,J2,M2,N2>&& sm, RSAs... args )
1493 {
1495 
1496  BLAZE_STATIC_ASSERT_MSG( I1 + M1 <= M2, "Invalid submatrix specification" );
1497  BLAZE_STATIC_ASSERT_MSG( J1 + N1 <= N2, "Invalid submatrix specification" );
1498 
1499  return submatrix<AF1,I1+I2,J1+J2,M1,N1>( sm.operand(), args... );
1500 }
1502 //*************************************************************************************************
1503 
1504 
1505 //*************************************************************************************************
1517 template< AlignmentFlag AF1 // Required alignment flag
1518  , size_t I // Index of the first row
1519  , size_t J // Index of the first column
1520  , size_t M // Number of rows
1521  , size_t N // Number of columns
1522  , typename MT // Type of the sparse submatrix
1523  , AlignmentFlag AF2 // Present alignment flag
1524  , bool SO // Storage order
1525  , bool DF // Density flag
1526  , typename... RSAs > // Optional submatrix arguments
1527 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF>& sm, RSAs... args )
1528 {
1530 
1531  constexpr bool isChecked( !Contains_v< TypeList<RSAs...>, Unchecked > );
1532 
1533  if( isChecked ) {
1534  if( ( I + M > sm.rows() ) || ( J + N > sm.columns() ) ) {
1535  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1536  }
1537  }
1538  else {
1539  BLAZE_USER_ASSERT( I + M <= sm.rows() , "Invalid submatrix specification" );
1540  BLAZE_USER_ASSERT( J + N <= sm.columns(), "Invalid submatrix specification" );
1541  }
1542 
1543  return submatrix<AF1>( sm.operand(), sm.row() + I, sm.column() + J, M, N, args... );
1544 }
1546 //*************************************************************************************************
1547 
1548 
1549 //*************************************************************************************************
1562 template< AlignmentFlag AF1 // Required alignment flag
1563  , size_t I // Index of the first row
1564  , size_t J // Index of the first column
1565  , size_t M // Number of rows
1566  , size_t N // Number of columns
1567  , typename MT // Type of the sparse submatrix
1568  , AlignmentFlag AF2 // Present alignment flag
1569  , bool SO // Storage order
1570  , bool DF // Density flag
1571  , typename... RSAs > // Optional submatrix arguments
1572 inline decltype(auto) submatrix( const Submatrix<MT,AF2,SO,DF>& sm, RSAs... args )
1573 {
1575 
1576  constexpr bool isChecked( !Contains_v< TypeList<RSAs...>, Unchecked > );
1577 
1578  if( isChecked ) {
1579  if( ( I + M > sm.rows() ) || ( J + N > sm.columns() ) ) {
1580  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1581  }
1582  }
1583  else {
1584  BLAZE_USER_ASSERT( I + M <= sm.rows() , "Invalid submatrix specification" );
1585  BLAZE_USER_ASSERT( J + N <= sm.columns(), "Invalid submatrix specification" );
1586  }
1587 
1588  return submatrix<AF1>( sm.operand(), sm.row() + I, sm.column() + J, M, N, args... );
1589 }
1591 //*************************************************************************************************
1592 
1593 
1594 //*************************************************************************************************
1607 template< AlignmentFlag AF1 // Required alignment flag
1608  , size_t I // Index of the first row
1609  , size_t J // Index of the first column
1610  , size_t M // Number of rows
1611  , size_t N // Number of columns
1612  , typename MT // Type of the sparse submatrix
1613  , AlignmentFlag AF2 // Present alignment flag
1614  , bool SO // Storage order
1615  , bool DF // Density flag
1616  , typename... RSAs > // Optional submatrix arguments
1617 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF>&& sm, RSAs... args )
1618 {
1620 
1621  constexpr bool isChecked( !Contains_v< TypeList<RSAs...>, Unchecked > );
1622 
1623  if( isChecked ) {
1624  if( ( I + M > sm.rows() ) || ( J + N > sm.columns() ) ) {
1625  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1626  }
1627  }
1628  else {
1629  BLAZE_USER_ASSERT( I + M <= sm.rows() , "Invalid submatrix specification" );
1630  BLAZE_USER_ASSERT( J + N <= sm.columns(), "Invalid submatrix specification" );
1631  }
1632 
1633  return submatrix<AF1>( sm.operand(), sm.row() + I, sm.column() + J, M, N, args... );
1634 }
1636 //*************************************************************************************************
1637 
1638 
1639 //*************************************************************************************************
1655 template< AlignmentFlag AF1 // Required alignment flag
1656  , typename MT // Type of the sparse submatrix
1657  , AlignmentFlag AF2 // Present alignment flag
1658  , bool SO // Storage order
1659  , bool DF // Density flag
1660  , size_t... CSAs // Compile time submatrix arguments
1661  , typename... RSAs > // Optional submatrix arguments
1662 inline decltype(auto)
1663  submatrix( Submatrix<MT,AF2,SO,DF,CSAs...>& sm, size_t row, size_t column,
1664  size_t m, size_t n, RSAs... args )
1665 {
1667 
1668  constexpr bool isChecked( !Contains_v< TypeList<RSAs...>, Unchecked > );
1669 
1670  if( isChecked ) {
1671  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
1672  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1673  }
1674  }
1675  else {
1676  BLAZE_USER_ASSERT( row + m <= sm.rows() , "Invalid submatrix specification" );
1677  BLAZE_USER_ASSERT( column + n <= sm.columns(), "Invalid submatrix specification" );
1678  }
1679 
1680  return submatrix<AF1>( sm.operand(), sm.row() + row, sm.column() + column, m, n, args... );
1681 }
1683 //*************************************************************************************************
1684 
1685 
1686 //*************************************************************************************************
1703 template< AlignmentFlag AF1 // Required alignment flag
1704  , typename MT // Type of the sparse submatrix
1705  , AlignmentFlag AF2 // Present alignment flag
1706  , bool SO // Storage order
1707  , bool DF // Density flag
1708  , size_t... CSAs // Compile time submatrix arguments
1709  , typename... RSAs > // Optional submatrix arguments
1710 inline decltype(auto)
1711  submatrix( const Submatrix<MT,AF2,SO,DF,CSAs...>& sm, size_t row, size_t column,
1712  size_t m, size_t n, RSAs... args )
1713 {
1715 
1716  constexpr bool isChecked( !Contains_v< TypeList<RSAs...>, Unchecked > );
1717 
1718  if( isChecked ) {
1719  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
1720  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1721  }
1722  }
1723  else {
1724  BLAZE_USER_ASSERT( row + m <= sm.rows() , "Invalid submatrix specification" );
1725  BLAZE_USER_ASSERT( column + n <= sm.columns(), "Invalid submatrix specification" );
1726  }
1727 
1728  return submatrix<AF1>( sm.operand(), sm.row() + row, sm.column() + column, m, n, args... );
1729 }
1731 //*************************************************************************************************
1732 
1733 
1734 //*************************************************************************************************
1751 template< AlignmentFlag AF1 // Required alignment flag
1752  , typename MT // Type of the sparse submatrix
1753  , AlignmentFlag AF2 // Present alignment flag
1754  , bool SO // Storage order
1755  , bool DF // Density flag
1756  , size_t... CSAs // Compile time submatrix arguments
1757  , typename... RSAs > // Optional submatrix arguments
1758 inline decltype(auto)
1759  submatrix( Submatrix<MT,AF2,SO,DF,CSAs...>&& sm, size_t row, size_t column,
1760  size_t m, size_t n, RSAs... args )
1761 {
1763 
1764  constexpr bool isChecked( !Contains_v< TypeList<RSAs...>, Unchecked > );
1765 
1766  if( isChecked ) {
1767  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
1768  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1769  }
1770  }
1771  else {
1772  BLAZE_USER_ASSERT( row + m <= sm.rows() , "Invalid submatrix specification" );
1773  BLAZE_USER_ASSERT( column + n <= sm.columns(), "Invalid submatrix specification" );
1774  }
1775 
1776  return submatrix<AF1>( sm.operand(), sm.row() + row, sm.column() + column, m, n, args... );
1777 }
1779 //*************************************************************************************************
1780 
1781 
1782 
1783 
1784 //=================================================================================================
1785 //
1786 // GLOBAL RESTRUCTURING FUNCTIONS (SUBVECTOR)
1787 //
1788 //=================================================================================================
1789 
1790 //*************************************************************************************************
1802 template< AlignmentFlag AF // Alignment flag
1803  , size_t... CSAs // Compile time subvector arguments
1804  , typename VT // Vector base type of the expression
1805  , typename... RSAs > // Runtime subvector arguments
1806 inline decltype(auto) subvector( const MatVecMultExpr<VT>& vector, RSAs... args )
1807 {
1809 
1810  using MT = RemoveReference_t< LeftOperand_t< VectorType_t<VT> > >;
1811 
1812  const SubvectorData<CSAs...> sd( args... );
1813 
1814  BLAZE_DECLTYPE_AUTO( left , (~vector).leftOperand() );
1815  BLAZE_DECLTYPE_AUTO( right, (~vector).rightOperand() );
1816 
1817  const size_t column( ( IsUpper_v<MT> )
1818  ?( ( !AF && IsStrictlyUpper_v<MT> )?( sd.offset() + 1UL ):( sd.offset() ) )
1819  :( 0UL ) );
1820  const size_t n( ( IsLower_v<MT> )
1821  ?( ( IsUpper_v<MT> )?( sd.size() )
1822  :( ( IsStrictlyLower_v<MT> && sd.size() > 0UL )
1823  ?( sd.offset() + sd.size() - 1UL )
1824  :( sd.offset() + sd.size() ) ) )
1825  :( ( IsUpper_v<MT> )?( left.columns() - column )
1826  :( left.columns() ) ) );
1827 
1828  return submatrix<AF>( left, sd.offset(), column, sd.size(), n ) * subvector<AF>( right, column, n );
1829 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1846 template< AlignmentFlag AF // Alignment flag
1847  , size_t... CSAs // Compile time subvector arguments
1848  , typename VT // Vector base type of the expression
1849  , typename... RSAs > // Runtime subvector arguments
1850 inline decltype(auto) subvector( const TVecMatMultExpr<VT>& vector, RSAs... args )
1851 {
1853 
1854  using MT = RemoveReference_t< RightOperand_t< VectorType_t<VT> > >;
1855 
1856  const SubvectorData<CSAs...> sd( args... );
1857 
1858  BLAZE_DECLTYPE_AUTO( left , (~vector).leftOperand() );
1859  BLAZE_DECLTYPE_AUTO( right, (~vector).rightOperand() );
1860 
1861  const size_t row( ( IsLower_v<MT> )
1862  ?( ( !AF && IsStrictlyLower_v<MT> )?( sd.offset() + 1UL ):( sd.offset() ) )
1863  :( 0UL ) );
1864  const size_t m( ( IsUpper_v<MT> )
1865  ?( ( IsLower_v<MT> )?( sd.size() )
1866  :( ( IsStrictlyUpper_v<MT> && sd.size() > 0UL )
1867  ?( sd.offset() + sd.size() - 1UL )
1868  :( sd.offset() + sd.size() ) ) )
1869  :( ( IsLower_v<MT> )?( right.rows() - row )
1870  :( right.rows() ) ) );
1871 
1872  return subvector<AF>( left, row, m ) * submatrix<AF>( right, row, sd.offset(), m, sd.size() );
1873 }
1875 //*************************************************************************************************
1876 
1877 
1878 //*************************************************************************************************
1890 template< AlignmentFlag AF // Alignment flag
1891  , size_t... CSAs // Compile time subvector arguments
1892  , typename VT // Vector base type of the expression
1893  , typename... RSAs > // Runtime subvector arguments
1894 inline decltype(auto) subvector( const MatReduceExpr<VT,columnwise>& vector, RSAs... args )
1895 {
1897 
1898  const SubvectorData<CSAs...> sd( args... );
1899  const size_t M( (~vector).operand().rows() );
1900 
1901  decltype(auto) sm( submatrix<AF>( (~vector).operand(), 0UL, sd.offset(), M, sd.size() ) );
1902  return reduce<columnwise>( sm, (~vector).operation() );
1903 }
1905 //*************************************************************************************************
1906 
1907 
1908 //*************************************************************************************************
1920 template< AlignmentFlag AF // Alignment flag
1921  , size_t... CSAs // Compile time subvector arguments
1922  , typename VT // Vector base type of the expression
1923  , typename... RSAs > // Runtime subvector arguments
1924 inline decltype(auto) subvector( const MatReduceExpr<VT,rowwise>& vector, RSAs... args )
1925 {
1927 
1928  const SubvectorData<CSAs...> sd( args... );
1929  const size_t N( (~vector).operand().columns() );
1930 
1931  decltype(auto) sm( submatrix<AF>( (~vector).operand(), sd.offset(), 0UL, sd.size(), N ) );
1932  return reduce<rowwise>( sm, (~vector).operation() );
1933 }
1935 //*************************************************************************************************
1936 
1937 
1938 
1939 
1940 //=================================================================================================
1941 //
1942 // GLOBAL RESTRUCTURING FUNCTIONS (ROW)
1943 //
1944 //=================================================================================================
1945 
1946 //*************************************************************************************************
1957 template< size_t I1 // Row index
1958  , typename MT // Type of the sparse submatrix
1959  , AlignmentFlag AF // Alignment flag
1960  , bool SO // Storage order
1961  , bool DF // Density flag
1962  , size_t I2 // Index of the first row
1963  , size_t J // Index of the first column
1964  , size_t M // Number of rows
1965  , size_t N // Number of columns
1966  , typename... RRAs > // Optional row arguments
1967 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
1968 {
1970 
1971  BLAZE_STATIC_ASSERT_MSG( I1 < M, "Invalid row access index" );
1972 
1973  return subvector<J,N>( row<I1+I2>( sm.operand(), args... ), unchecked );
1974 }
1976 //*************************************************************************************************
1977 
1978 
1979 //*************************************************************************************************
1991 template< size_t I1 // Row index
1992  , typename MT // Type of the sparse submatrix
1993  , AlignmentFlag AF // Alignment flag
1994  , bool SO // Storage order
1995  , bool DF // Density flag
1996  , size_t I2 // Index of the first row
1997  , size_t J // Index of the first column
1998  , size_t M // Number of rows
1999  , size_t N // Number of columns
2000  , typename... RRAs > // Optional row arguments
2001 inline decltype(auto) row( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
2002 {
2004 
2005  BLAZE_STATIC_ASSERT_MSG( I1 < M, "Invalid row access index" );
2006 
2007  return subvector<J,N>( row<I1+I2>( sm.operand(), args... ), unchecked );
2008 }
2010 //*************************************************************************************************
2011 
2012 
2013 //*************************************************************************************************
2025 template< size_t I1 // Row index
2026  , typename MT // Type of the sparse submatrix
2027  , AlignmentFlag AF // Alignment flag
2028  , bool SO // Storage order
2029  , bool DF // Density flag
2030  , size_t I2 // Index of the first row
2031  , size_t J // Index of the first column
2032  , size_t M // Number of rows
2033  , size_t N // Number of columns
2034  , typename... RRAs > // Optional row arguments
2035 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RRAs... args )
2036 {
2038 
2039  BLAZE_STATIC_ASSERT_MSG( I1 < M, "Invalid row access index" );
2040 
2041  return subvector<J,N>( row<I1+I2>( sm.operand(), args... ), unchecked );
2042 }
2044 //*************************************************************************************************
2045 
2046 
2047 //*************************************************************************************************
2060 template< typename MT // Type of the sparse submatrix
2061  , AlignmentFlag AF // Alignment flag
2062  , bool SO // Storage order
2063  , bool DF // Density flag
2064  , size_t I // Index of the first row
2065  , size_t J // Index of the first column
2066  , size_t M // Number of rows
2067  , size_t N // Number of columns
2068  , typename... RRAs > // Optional row arguments
2069 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RRAs... args )
2070 {
2072 
2073  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2074 
2075  if( isChecked ) {
2076  if( ( index >= M ) ) {
2077  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2078  }
2079  }
2080  else {
2081  BLAZE_USER_ASSERT( index < M, "Invalid row access index" );
2082  }
2083 
2084  return subvector<J,N>( row( sm.operand(), I+index, args... ), unchecked );
2085 }
2087 //*************************************************************************************************
2088 
2089 
2090 //*************************************************************************************************
2104 template< typename MT // Type of the sparse submatrix
2105  , AlignmentFlag AF // Alignment flag
2106  , bool SO // Storage order
2107  , bool DF // Density flag
2108  , size_t I // Index of the first row
2109  , size_t J // Index of the first column
2110  , size_t M // Number of rows
2111  , size_t N // Number of columns
2112  , typename... RRAs > // Optional row arguments
2113 inline decltype(auto) row( const Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RRAs... args )
2114 {
2116 
2117  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2118 
2119  if( isChecked ) {
2120  if( ( index >= M ) ) {
2121  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2122  }
2123  }
2124  else {
2125  BLAZE_USER_ASSERT( index < M, "Invalid row access index" );
2126  }
2127 
2128  return subvector<J,N>( row( sm.operand(), I+index, args... ), unchecked );
2129 }
2131 //*************************************************************************************************
2132 
2133 
2134 //*************************************************************************************************
2148 template< typename MT // Type of the sparse submatrix
2149  , AlignmentFlag AF // Alignment flag
2150  , bool SO // Storage order
2151  , bool DF // Density flag
2152  , size_t I // Index of the first row
2153  , size_t J // Index of the first column
2154  , size_t M // Number of rows
2155  , size_t N // Number of columns
2156  , typename... RRAs > // Optional row arguments
2157 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I,J,M,N>&& sm, size_t index, RRAs... args )
2158 {
2160 
2161  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2162 
2163  if( isChecked ) {
2164  if( ( index >= M ) ) {
2165  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2166  }
2167  }
2168  else {
2169  BLAZE_USER_ASSERT( index < M, "Invalid row access index" );
2170  }
2171 
2172  return subvector<J,N>( row( sm.operand(), I+index, args... ), unchecked );
2173 }
2175 //*************************************************************************************************
2176 
2177 
2178 //*************************************************************************************************
2190 template< size_t... CRAs // Compile time row arguments
2191  , typename MT // Type of the sparse submatrix
2192  , AlignmentFlag AF // Alignment flag
2193  , bool SO // Storage order
2194  , bool DF // Density flag
2195  , typename... RRAs > // Runtime row arguments
2196 inline decltype(auto) row( Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2197 {
2199 
2200  const RowData<CRAs...> rd( args... );
2201 
2202  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2203 
2204  if( isChecked ) {
2205  if( ( rd.row() >= sm.rows() ) ) {
2206  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2207  }
2208  }
2209  else {
2210  BLAZE_USER_ASSERT( rd.row() < sm.rows(), "Invalid row access index" );
2211  }
2212 
2213  const size_t index( rd.row() + sm.row() );
2214 
2215  return subvector( row( sm.operand(), index, args... ), sm.column(), sm.columns(), unchecked );
2216 }
2218 //*************************************************************************************************
2219 
2220 
2221 //*************************************************************************************************
2234 template< size_t... CRAs // Compile time row arguments
2235  , typename MT // Type of the sparse submatrix
2236  , AlignmentFlag AF // Alignment flag
2237  , bool SO // Storage order
2238  , bool DF // Density flag
2239  , typename... RRAs > // Runtime row arguments
2240 inline decltype(auto) row( const Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2241 {
2243 
2244  const RowData<CRAs...> rd( args... );
2245 
2246  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2247 
2248  if( isChecked ) {
2249  if( ( rd.row() >= sm.rows() ) ) {
2250  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2251  }
2252  }
2253  else {
2254  BLAZE_USER_ASSERT( rd.row() < sm.rows(), "Invalid row access index" );
2255  }
2256 
2257  const size_t index( rd.row() + sm.row() );
2258 
2259  return subvector( row( sm.operand(), index, args... ), sm.column(), sm.columns(), unchecked );
2260 }
2262 //*************************************************************************************************
2263 
2264 
2265 //*************************************************************************************************
2278 template< size_t... CRAs // Compile time row arguments
2279  , typename MT // Type of the sparse submatrix
2280  , AlignmentFlag AF // Alignment flag
2281  , bool SO // Storage order
2282  , bool DF // Density flag
2283  , typename... RRAs > // Runtime row arguments
2284 inline decltype(auto) row( Submatrix<MT,AF,SO,DF>&& sm, RRAs... args )
2285 {
2287 
2288  const RowData<CRAs...> rd( args... );
2289 
2290  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2291 
2292  if( isChecked ) {
2293  if( ( rd.row() >= sm.rows() ) ) {
2294  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2295  }
2296  }
2297  else {
2298  BLAZE_USER_ASSERT( rd.row() < sm.rows(), "Invalid row access index" );
2299  }
2300 
2301  const size_t index( rd.row() + sm.row() );
2302 
2303  return subvector( row( sm.operand(), index, args... ), sm.column(), sm.columns(), unchecked );
2304 }
2306 //*************************************************************************************************
2307 
2308 
2309 
2310 
2311 //=================================================================================================
2312 //
2313 // GLOBAL RESTRUCTURING FUNCTIONS (ROWS)
2314 //
2315 //=================================================================================================
2316 
2317 //*************************************************************************************************
2328 template< size_t I1 // First row index
2329  , size_t... Is // Remaining row indices
2330  , typename MT // Type of the sparse submatrix
2331  , AlignmentFlag AF // Alignment flag
2332  , bool SO // Storage order
2333  , bool DF // Density flag
2334  , size_t I2 // Index of the first row
2335  , size_t J // Index of the first column
2336  , size_t M // Number of rows
2337  , size_t N // Number of columns
2338  , typename... RRAs > // Optional row arguments
2339 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
2340 {
2342 
2343  return submatrix<0UL,J,sizeof...(Is)+1UL,N>(
2344  rows( sm.operand(), make_shifted_index_subsequence<I2,M,I1,Is...>(), args... ), unchecked );
2345 }
2347 //*************************************************************************************************
2348 
2349 
2350 //*************************************************************************************************
2362 template< size_t I1 // First row index
2363  , size_t... Is // Remaining row indices
2364  , typename MT // Type of the sparse submatrix
2365  , AlignmentFlag AF // Alignment flag
2366  , bool SO // Storage order
2367  , bool DF // Density flag
2368  , size_t I2 // Index of the first row
2369  , size_t J // Index of the first column
2370  , size_t M // Number of rows
2371  , size_t N // Number of columns
2372  , typename... RRAs > // Optional row arguments
2373 inline decltype(auto) rows( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
2374 {
2376 
2377  return submatrix<0UL,J,sizeof...(Is)+1UL,N>(
2378  rows( sm.operand(), make_shifted_index_subsequence<I2,M,I1,Is...>(), args... ), unchecked );
2379 }
2381 //*************************************************************************************************
2382 
2383 
2384 //*************************************************************************************************
2396 template< size_t I1 // First row index
2397  , size_t... Is // Remaining row indices
2398  , typename MT // Type of the sparse submatrix
2399  , AlignmentFlag AF // Alignment flag
2400  , bool SO // Storage order
2401  , bool DF // Density flag
2402  , size_t I2 // Index of the first row
2403  , size_t J // Index of the first column
2404  , size_t M // Number of rows
2405  , size_t N // Number of columns
2406  , typename... RRAs > // Optional row arguments
2407 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RRAs... args )
2408 {
2410 
2411  return submatrix<0UL,J,sizeof...(Is)+1UL,N>(
2412  rows( sm.operand(), make_shifted_index_subsequence<I2,M,I1,Is...>(), args... ), unchecked );
2413 }
2415 //*************************************************************************************************
2416 
2417 
2418 //*************************************************************************************************
2430 template< size_t I1 // First row index
2431  , size_t... Is // Remaining row indices
2432  , typename MT // Type of the sparse submatrix
2433  , AlignmentFlag AF // Alignment flag
2434  , bool SO // Storage order
2435  , bool DF // Density flag
2436  , typename... RRAs > // Optional row arguments
2437 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2438 {
2440 
2441  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2442 
2443  if( isChecked ) {
2444  static constexpr size_t indices[] = { I1, Is... };
2445  for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
2446  if( sm.rows() <= indices[i] ) {
2447  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2448  }
2449  }
2450  }
2451 
2452  return submatrix( rows( sm.operand(), { I1+sm.row(), Is+sm.row()... }, args... ),
2453  0UL, sm.column(), sizeof...(Is)+1UL, sm.columns(), unchecked );
2454 }
2456 //*************************************************************************************************
2457 
2458 
2459 //*************************************************************************************************
2472 template< size_t I1 // First row index
2473  , size_t... Is // Remaining row indices
2474  , typename MT // Type of the sparse submatrix
2475  , AlignmentFlag AF // Alignment flag
2476  , bool SO // Storage order
2477  , bool DF // Density flag
2478  , typename... RRAs > // Optional row arguments
2479 inline decltype(auto) rows( const Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2480 {
2482 
2483  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2484 
2485  if( isChecked ) {
2486  static constexpr size_t indices[] = { I1, Is... };
2487  for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
2488  if( sm.rows() <= indices[i] ) {
2489  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2490  }
2491  }
2492  }
2493 
2494  return submatrix( rows( sm.operand(), { I1+sm.row(), Is+sm.row()... }, args... ),
2495  0UL, sm.column(), sizeof...(Is)+1UL, sm.columns(), unchecked );
2496 }
2498 //*************************************************************************************************
2499 
2500 
2501 //*************************************************************************************************
2514 template< size_t I1 // First row index
2515  , size_t... Is // Remaining row indices
2516  , typename MT // Type of the sparse submatrix
2517  , AlignmentFlag AF // Alignment flag
2518  , bool SO // Storage order
2519  , bool DF // Density flag
2520  , typename... RRAs > // Optional row arguments
2521 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF>&& sm, RRAs... args )
2522 {
2524 
2525  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2526 
2527  if( isChecked ) {
2528  static constexpr size_t indices[] = { I1, Is... };
2529  for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
2530  if( sm.rows() <= indices[i] ) {
2531  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2532  }
2533  }
2534  }
2535 
2536  return submatrix( rows( sm.operand(), { I1+sm.row(), Is+sm.row()... }, args... ),
2537  0UL, sm.column(), sizeof...(Is)+1UL, sm.columns(), unchecked );
2538 }
2540 //*************************************************************************************************
2541 
2542 
2543 //*************************************************************************************************
2557 template< typename MT // Type of the sparse submatrix
2558  , AlignmentFlag AF // Alignment flag
2559  , bool SO // Storage order
2560  , bool DF // Density flag
2561  , size_t... CSAs // Compile time submatrix arguments
2562  , typename T // Type of the row indices
2563  , typename... RRAs > // Optional row arguments
2564 inline decltype(auto)
2565  rows( Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RRAs... args )
2566 {
2568 
2569  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2570 
2571  if( isChecked ) {
2572  for( size_t i=0UL; i<n; ++i ) {
2573  if( sm.rows() <= indices[i] ) {
2574  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row specification" );
2575  }
2576  }
2577  }
2578 
2579  SmallArray<size_t,128UL> newIndices( indices, indices+n );
2580  std::for_each( newIndices.begin(), newIndices.end(),
2581  [row=sm.row()]( size_t& index ){ index += row; } );
2582 
2583  return submatrix( rows( sm.operand(), newIndices.data(), n, args... ),
2584  0UL, sm.column(), n, sm.columns(), unchecked );
2585 }
2587 //*************************************************************************************************
2588 
2589 
2590 //*************************************************************************************************
2605 template< typename MT // Type of the sparse submatrix
2606  , AlignmentFlag AF // Alignment flag
2607  , bool SO // Storage order
2608  , bool DF // Density flag
2609  , size_t... CSAs // Compile time submatrix arguments
2610  , typename T // Type of the row indices
2611  , typename... RRAs > // Optional row arguments
2612 inline decltype(auto)
2613  rows( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RRAs... args )
2614 {
2616 
2617  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2618 
2619  if( isChecked ) {
2620  for( size_t i=0UL; i<n; ++i ) {
2621  if( sm.rows() <= indices[i] ) {
2622  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row specification" );
2623  }
2624  }
2625  }
2626 
2627  SmallArray<size_t,128UL> newIndices( indices, indices+n );
2628  std::for_each( newIndices.begin(), newIndices.end(),
2629  [row=sm.row()]( size_t& index ){ index += row; } );
2630 
2631  return submatrix( rows( sm.operand(), newIndices.data(), n, args... ),
2632  0UL, sm.column(), n, sm.columns(), unchecked );
2633 }
2635 //*************************************************************************************************
2636 
2637 
2638 //*************************************************************************************************
2653 template< typename MT // Type of the sparse submatrix
2654  , AlignmentFlag AF // Alignment flag
2655  , bool SO // Storage order
2656  , bool DF // Density flag
2657  , size_t... CSAs // Compile time submatrix arguments
2658  , typename T // Type of the row indices
2659  , typename... RRAs > // Optional row arguments
2660 inline decltype(auto)
2661  rows( Submatrix<MT,AF,SO,DF,CSAs...>&& sm, const T* indices, size_t n, RRAs... args )
2662 {
2664 
2665  constexpr bool isChecked( !Contains_v< TypeList<RRAs...>, Unchecked > );
2666 
2667  if( isChecked ) {
2668  for( size_t i=0UL; i<n; ++i ) {
2669  if( sm.rows() <= indices[i] ) {
2670  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row specification" );
2671  }
2672  }
2673  }
2674 
2675  SmallArray<size_t,128UL> newIndices( indices, indices+n );
2676  std::for_each( newIndices.begin(), newIndices.end(),
2677  [row=sm.row()]( size_t& index ){ index += row; } );
2678 
2679  return submatrix( rows( sm.operand(), newIndices.data(), n, args... ),
2680  0UL, sm.column(), n, sm.columns(), unchecked );
2681 }
2683 //*************************************************************************************************
2684 
2685 
2686 
2687 
2688 //=================================================================================================
2689 //
2690 // GLOBAL RESTRUCTURING FUNCTIONS (COLUMN)
2691 //
2692 //=================================================================================================
2693 
2694 //*************************************************************************************************
2705 template< size_t I1 // Column index
2706  , typename MT // Type of the sparse submatrix
2707  , AlignmentFlag AF // Alignment flag
2708  , bool SO // Storage order
2709  , bool DF // Density flag
2710  , size_t I2 // Index of the first row
2711  , size_t J // Index of the first column
2712  , size_t M // Number of rows
2713  , size_t N // Number of columns
2714  , typename... RCAs > // Optional column arguments
2715 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
2716 {
2718 
2719  BLAZE_STATIC_ASSERT_MSG( I1 < N, "Invalid column access index" );
2720 
2721  return subvector<I2,M>( column<I1+J>( sm.operand(), args... ), unchecked );
2722 }
2724 //*************************************************************************************************
2725 
2726 
2727 //*************************************************************************************************
2739 template< size_t I1 // Column index
2740  , typename MT // Type of the sparse submatrix
2741  , AlignmentFlag AF // Alignment flag
2742  , bool SO // Storage order
2743  , bool DF // Density flag
2744  , size_t I2 // Index of the first row
2745  , size_t J // Index of the first column
2746  , size_t M // Number of rows
2747  , size_t N // Number of columns
2748  , typename... RCAs > // Optional column arguments
2749 inline decltype(auto) column( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
2750 {
2752 
2753  BLAZE_STATIC_ASSERT_MSG( I1 < N, "Invalid column access index" );
2754 
2755  return subvector<I2,M>( column<I1+J>( sm.operand(), args... ), unchecked );
2756 }
2758 //*************************************************************************************************
2759 
2760 
2761 //*************************************************************************************************
2773 template< size_t I1 // Column index
2774  , typename MT // Type of the sparse submatrix
2775  , AlignmentFlag AF // Alignment flag
2776  , bool SO // Storage order
2777  , bool DF // Density flag
2778  , size_t I2 // Index of the first row
2779  , size_t J // Index of the first column
2780  , size_t M // Number of rows
2781  , size_t N // Number of columns
2782  , typename... RCAs > // Optional column arguments
2783 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RCAs... args )
2784 {
2786 
2787  BLAZE_STATIC_ASSERT_MSG( I1 < N, "Invalid column access index" );
2788 
2789  return subvector<I2,M>( column<I1+J>( sm.operand(), args... ), unchecked );
2790 }
2792 //*************************************************************************************************
2793 
2794 
2795 //*************************************************************************************************
2808 template< typename MT // Type of the sparse submatrix
2809  , AlignmentFlag AF // Alignment flag
2810  , bool SO // Storage order
2811  , bool DF // Density flag
2812  , size_t I // Index of the first row
2813  , size_t J // Index of the first column
2814  , size_t M // Number of rows
2815  , size_t N // Number of columns
2816  , typename... RCAs > // Optional column arguments
2817 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RCAs... args )
2818 {
2820 
2821  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
2822 
2823  if( isChecked ) {
2824  if( ( index >= N ) ) {
2825  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2826  }
2827  }
2828  else {
2829  BLAZE_USER_ASSERT( index < N, "Invalid column access index" );
2830  }
2831 
2832  return subvector<I,M>( column( sm.operand(), J+index, args... ), unchecked );
2833 }
2835 //*************************************************************************************************
2836 
2837 
2838 //*************************************************************************************************
2852 template< typename MT // Type of the sparse submatrix
2853  , AlignmentFlag AF // Alignment flag
2854  , bool SO // Storage order
2855  , bool DF // Density flag
2856  , size_t I // Index of the first row
2857  , size_t J // Index of the first column
2858  , size_t M // Number of rows
2859  , size_t N // Number of columns
2860  , typename... RCAs > // Optional column arguments
2861 inline decltype(auto) column( const Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RCAs... args )
2862 {
2864 
2865  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
2866 
2867  if( isChecked ) {
2868  if( ( index >= N ) ) {
2869  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2870  }
2871  }
2872  else {
2873  BLAZE_USER_ASSERT( index < N, "Invalid column access index" );
2874  }
2875 
2876  return subvector<I,M>( column( sm.operand(), J+index, args... ), unchecked );
2877 }
2879 //*************************************************************************************************
2880 
2881 
2882 //*************************************************************************************************
2896 template< typename MT // Type of the sparse submatrix
2897  , AlignmentFlag AF // Alignment flag
2898  , bool SO // Storage order
2899  , bool DF // Density flag
2900  , size_t I // Index of the first row
2901  , size_t J // Index of the first column
2902  , size_t M // Number of rows
2903  , size_t N // Number of columns
2904  , typename... RCAs > // Optional column arguments
2905 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I,J,M,N>&& sm, size_t index, RCAs... args )
2906 {
2908 
2909  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
2910 
2911  if( isChecked ) {
2912  if( ( index >= N ) ) {
2913  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2914  }
2915  }
2916  else {
2917  BLAZE_USER_ASSERT( index < N, "Invalid column access index" );
2918  }
2919 
2920  return subvector<I,M>( column( sm.operand(), J+index, args... ), unchecked );
2921 }
2923 //*************************************************************************************************
2924 
2925 
2926 //*************************************************************************************************
2938 template< size_t... CCAs // Compile time column arguments
2939  , typename MT // Type of the sparse submatrix
2940  , AlignmentFlag AF // Alignment flag
2941  , bool SO // Storage order
2942  , bool DF // Density flag
2943  , typename... RCAs > // Runtime column arguments
2944 inline decltype(auto) column( Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
2945 {
2947 
2948  const ColumnData<CCAs...> cd( args... );
2949 
2950  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
2951 
2952  if( isChecked ) {
2953  if( ( cd.column() >= sm.columns() ) ) {
2954  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2955  }
2956  }
2957  else {
2958  BLAZE_USER_ASSERT( cd.column() < sm.columns(), "Invalid column access index" );
2959  }
2960 
2961  const size_t index( cd.column() + sm.column() );
2962 
2963  return subvector( column( sm.operand(), index, args... ), sm.row(), sm.rows(), unchecked );
2964 }
2966 //*************************************************************************************************
2967 
2968 
2969 //*************************************************************************************************
2982 template< size_t... CCAs // Compile time column arguments
2983  , typename MT // Type of the sparse submatrix
2984  , AlignmentFlag AF // Alignment flag
2985  , bool SO // Storage order
2986  , bool DF // Density flag
2987  , typename... RCAs > // Runtime column arguments
2988 inline decltype(auto) column( const Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
2989 {
2991 
2992  const ColumnData<CCAs...> cd( args... );
2993 
2994  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
2995 
2996  if( isChecked ) {
2997  if( ( cd.column() >= sm.columns() ) ) {
2998  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2999  }
3000  }
3001  else {
3002  BLAZE_USER_ASSERT( cd.column() < sm.columns(), "Invalid column access index" );
3003  }
3004 
3005  const size_t index( cd.column() + sm.column() );
3006 
3007  return subvector( column( sm.operand(), index, args... ), sm.row(), sm.rows(), unchecked );
3008 }
3010 //*************************************************************************************************
3011 
3012 
3013 //*************************************************************************************************
3026 template< size_t... CCAs // Compile time column arguments
3027  , typename MT // Type of the sparse submatrix
3028  , AlignmentFlag AF // Alignment flag
3029  , bool SO // Storage order
3030  , bool DF // Density flag
3031  , typename... RCAs > // Runtime column arguments
3032 inline decltype(auto) column( Submatrix<MT,AF,SO,DF>&& sm, RCAs... args )
3033 {
3035 
3036  const ColumnData<CCAs...> cd( args... );
3037 
3038  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3039 
3040  if( isChecked ) {
3041  if( ( cd.column() >= sm.columns() ) ) {
3042  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3043  }
3044  }
3045  else {
3046  BLAZE_USER_ASSERT( cd.column() < sm.columns(), "Invalid column access index" );
3047  }
3048 
3049  const size_t index( cd.column() + sm.column() );
3050 
3051  return subvector( column( sm.operand(), index, args... ), sm.row(), sm.rows(), unchecked );
3052 }
3054 //*************************************************************************************************
3055 
3056 
3057 
3058 
3059 //=================================================================================================
3060 //
3061 // GLOBAL RESTRUCTURING FUNCTIONS (COLUMNS)
3062 //
3063 //=================================================================================================
3064 
3065 //*************************************************************************************************
3076 template< size_t I1 // First column index
3077  , size_t... Is // Remaining column indices
3078  , typename MT // Type of the sparse submatrix
3079  , AlignmentFlag AF // Alignment flag
3080  , bool SO // Storage order
3081  , bool DF // Density flag
3082  , size_t I2 // Index of the first row
3083  , size_t J // Index of the first column
3084  , size_t M // Number of rows
3085  , size_t N // Number of columns
3086  , typename... RCAs > // Optional column arguments
3087 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
3088 {
3090 
3091  return submatrix<I2,0UL,M,sizeof...(Is)+1UL>(
3092  columns( sm.operand(), make_shifted_index_subsequence<J,N,I1,Is...>(), args... ), unchecked );
3093 }
3095 //*************************************************************************************************
3096 
3097 
3098 //*************************************************************************************************
3110 template< size_t I1 // First column index
3111  , size_t... Is // Remaining column indices
3112  , typename MT // Type of the sparse submatrix
3113  , AlignmentFlag AF // Alignment flag
3114  , bool SO // Storage order
3115  , bool DF // Density flag
3116  , size_t I2 // Index of the first row
3117  , size_t J // Index of the first column
3118  , size_t M // Number of rows
3119  , size_t N // Number of columns
3120  , typename... RCAs > // Optional column arguments
3121 inline decltype(auto) columns( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
3122 {
3124 
3125  return submatrix<I2,0UL,M,sizeof...(Is)+1UL>(
3126  columns( sm.operand(), make_shifted_index_subsequence<J,N,I1,Is...>(), args... ), unchecked );
3127 }
3129 //*************************************************************************************************
3130 
3131 
3132 //*************************************************************************************************
3144 template< size_t I1 // First column index
3145  , size_t... Is // Remaining column indices
3146  , typename MT // Type of the sparse submatrix
3147  , AlignmentFlag AF // Alignment flag
3148  , bool SO // Storage order
3149  , bool DF // Density flag
3150  , size_t I2 // Index of the first row
3151  , size_t J // Index of the first column
3152  , size_t M // Number of rows
3153  , size_t N // Number of columns
3154  , typename... RCAs > // Optional column arguments
3155 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RCAs... args )
3156 {
3158 
3159  return submatrix<I2,0UL,M,sizeof...(Is)+1UL>(
3160  columns( sm.operand(), make_shifted_index_subsequence<J,N,I1,Is...>(), args... ), unchecked );
3161 }
3163 //*************************************************************************************************
3164 
3165 
3166 //*************************************************************************************************
3178 template< size_t I1 // First column index
3179  , size_t... Is // Remaining column indices
3180  , typename MT // Type of the sparse submatrix
3181  , AlignmentFlag AF // Alignment flag
3182  , bool SO // Storage order
3183  , bool DF // Density flag
3184  , typename... RCAs > // Optional column arguments
3185 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
3186 {
3188 
3189  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3190 
3191  if( isChecked ) {
3192  static constexpr size_t indices[] = { I1, Is... };
3193  for( size_t j=0UL; j<sizeof...(Is)+1UL; ++j ) {
3194  if( sm.columns() <= indices[j] ) {
3195  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3196  }
3197  }
3198  }
3199 
3200  return submatrix( columns( sm.operand(), { I1+sm.column(), Is+sm.column()... }, args... ),
3201  sm.row(), 0UL, sm.rows(), sizeof...(Is)+1UL, unchecked );
3202 }
3204 //*************************************************************************************************
3205 
3206 
3207 //*************************************************************************************************
3220 template< size_t I1 // First column index
3221  , size_t... Is // Remaining column indices
3222  , typename MT // Type of the sparse submatrix
3223  , AlignmentFlag AF // Alignment flag
3224  , bool SO // Storage order
3225  , bool DF // Density flag
3226  , typename... RCAs > // Optional column arguments
3227 inline decltype(auto) columns( const Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
3228 {
3230 
3231  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3232 
3233  if( isChecked ) {
3234  static constexpr size_t indices[] = { I1, Is... };
3235  for( size_t j=0UL; j<sizeof...(Is)+1UL; ++j ) {
3236  if( sm.columns() <= indices[j] ) {
3237  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3238  }
3239  }
3240  }
3241 
3242  return submatrix( columns( sm.operand(), { I1+sm.column(), Is+sm.column()... }, args... ),
3243  sm.row(), 0UL, sm.rows(), sizeof...(Is)+1UL, unchecked );
3244 }
3246 //*************************************************************************************************
3247 
3248 
3249 //*************************************************************************************************
3262 template< size_t I1 // First column index
3263  , size_t... Is // Remaining column indices
3264  , typename MT // Type of the sparse submatrix
3265  , AlignmentFlag AF // Alignment flag
3266  , bool SO // Storage order
3267  , bool DF // Density flag
3268  , typename... RCAs > // Optional column arguments
3269 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF>&& sm, RCAs... args )
3270 {
3272 
3273  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3274 
3275  if( isChecked ) {
3276  static constexpr size_t indices[] = { I1, Is... };
3277  for( size_t j=0UL; j<sizeof...(Is)+1UL; ++j ) {
3278  if( sm.columns() <= indices[j] ) {
3279  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3280  }
3281  }
3282  }
3283 
3284  return submatrix( columns( sm.operand(), { I1+sm.column(), Is+sm.column()... }, args... ),
3285  sm.row(), 0UL, sm.rows(), sizeof...(Is)+1UL, unchecked );
3286 }
3288 //*************************************************************************************************
3289 
3290 
3291 //*************************************************************************************************
3305 template< typename MT // Type of the sparse submatrix
3306  , AlignmentFlag AF // Alignment flag
3307  , bool SO // Storage order
3308  , bool DF // Density flag
3309  , size_t... CSAs // Compile time submatrix arguments
3310  , typename T // Type of the column indices
3311  , typename... RCAs > // Optional column arguments
3312 inline decltype(auto)
3313  columns( Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RCAs... args )
3314 {
3316 
3317  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3318 
3319  if( isChecked ) {
3320  for( size_t j=0UL; j<n; ++j ) {
3321  if( sm.columns() <= indices[j] ) {
3322  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column specification" );
3323  }
3324  }
3325  }
3326 
3327  SmallArray<size_t,128UL> newIndices( indices, indices+n );
3328  std::for_each( newIndices.begin(), newIndices.end(),
3329  [column=sm.column()]( size_t& index ){ index += column; } );
3330 
3331  return submatrix( columns( sm.operand(), newIndices.data(), n, args... ),
3332  sm.row(), 0UL, sm.rows(), n, unchecked );
3333 }
3335 //*************************************************************************************************
3336 
3337 
3338 //*************************************************************************************************
3353 template< typename MT // Type of the sparse submatrix
3354  , AlignmentFlag AF // Alignment flag
3355  , bool SO // Storage order
3356  , bool DF // Density flag
3357  , size_t... CSAs // Compile time submatrix arguments
3358  , typename T // Type of the column indices
3359  , typename... RCAs > // Optional column arguments
3360 inline decltype(auto)
3361  columns( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RCAs... args )
3362 {
3364 
3365  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3366 
3367  if( isChecked ) {
3368  for( size_t j=0UL; j<n; ++j ) {
3369  if( sm.columns() <= indices[j] ) {
3370  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column specification" );
3371  }
3372  }
3373  }
3374 
3375  SmallArray<size_t,128UL> newIndices( indices, indices+n );
3376  std::for_each( newIndices.begin(), newIndices.end(),
3377  [column=sm.column()]( size_t& index ){ index += column; } );
3378 
3379  return submatrix( columns( sm.operand(), newIndices.data(), n, args... ),
3380  sm.row(), 0UL, sm.rows(), n, unchecked );
3381 }
3383 //*************************************************************************************************
3384 
3385 
3386 //*************************************************************************************************
3401 template< typename MT // Type of the sparse submatrix
3402  , AlignmentFlag AF // Alignment flag
3403  , bool SO // Storage order
3404  , bool DF // Density flag
3405  , size_t... CSAs // Compile time submatrix arguments
3406  , typename T // Type of the column indices
3407  , typename... RCAs > // Optional column arguments
3408 inline decltype(auto)
3409  columns( Submatrix<MT,AF,SO,DF,CSAs...>&& sm, const T* indices, size_t n, RCAs... args )
3410 {
3412 
3413  constexpr bool isChecked( !Contains_v< TypeList<RCAs...>, Unchecked > );
3414 
3415  if( isChecked ) {
3416  for( size_t j=0UL; j<n; ++j ) {
3417  if( sm.columns() <= indices[j] ) {
3418  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column specification" );
3419  }
3420  }
3421  }
3422 
3423  SmallArray<size_t,128UL> newIndices( indices, indices+n );
3424  std::for_each( newIndices.begin(), newIndices.end(),
3425  [column=sm.column()]( size_t& index ){ index += column; } );
3426 
3427  return submatrix( columns( sm.operand(), newIndices.data(), n, args... ),
3428  sm.row(), 0UL, sm.rows(), n, unchecked );
3429 }
3431 //*************************************************************************************************
3432 
3433 
3434 
3435 
3436 //=================================================================================================
3437 //
3438 // SUBMATRIX OPERATORS
3439 //
3440 //=================================================================================================
3441 
3442 //*************************************************************************************************
3450 template< typename MT // Type of the matrix
3451  , AlignmentFlag AF // Alignment flag
3452  , bool SO // Storage order
3453  , bool DF // Density flag
3454  , size_t... CSAs > // Compile time submatrix arguments
3455 inline void reset( Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3456 {
3457  sm.reset();
3458 }
3460 //*************************************************************************************************
3461 
3462 
3463 //*************************************************************************************************
3471 template< typename MT // Type of the matrix
3472  , AlignmentFlag AF // Alignment flag
3473  , bool SO // Storage order
3474  , bool DF // Density flag
3475  , size_t... CSAs > // Compile time submatrix arguments
3476 inline void reset( Submatrix<MT,AF,SO,DF,CSAs...>&& sm )
3477 {
3478  sm.reset();
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3498 template< typename MT // Type of the matrix
3499  , AlignmentFlag AF // Alignment flag
3500  , bool SO // Storage order
3501  , bool DF // Density flag
3502  , size_t... CSAs > // Compile time submatrix arguments
3503 inline void reset( Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i )
3504 {
3505  sm.reset( i );
3506 }
3508 //*************************************************************************************************
3509 
3510 
3511 //*************************************************************************************************
3521 template< typename MT // Type of the matrix
3522  , AlignmentFlag AF // Alignment flag
3523  , bool SO // Storage order
3524  , bool DF // Density flag
3525  , size_t... CSAs > // Compile time submatrix arguments
3526 inline void clear( Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3527 {
3528  sm.reset();
3529 }
3531 //*************************************************************************************************
3532 
3533 
3534 //*************************************************************************************************
3544 template< typename MT // Type of the matrix
3545  , AlignmentFlag AF // Alignment flag
3546  , bool SO // Storage order
3547  , bool DF // Density flag
3548  , size_t... CSAs > // Compile time submatrix arguments
3549 inline void clear( Submatrix<MT,AF,SO,DF,CSAs...>&& sm )
3550 {
3551  sm.reset();
3552 }
3554 //*************************************************************************************************
3555 
3556 
3557 //*************************************************************************************************
3583 template< bool RF // Relaxation flag
3584  , typename MT // Type of the dense matrix
3585  , AlignmentFlag AF // Alignment flag
3586  , bool SO // Storage order
3587  , size_t... CSAs > // Compile time submatrix arguments
3588 inline bool isDefault( const Submatrix<MT,AF,SO,true,CSAs...>& sm )
3589 {
3590  using blaze::isDefault;
3591 
3592  if( SO == rowMajor ) {
3593  for( size_t i=0UL; i<(~sm).rows(); ++i )
3594  for( size_t j=0UL; j<(~sm).columns(); ++j )
3595  if( !isDefault<RF>( (~sm)(i,j) ) )
3596  return false;
3597  }
3598  else {
3599  for( size_t j=0UL; j<(~sm).columns(); ++j )
3600  for( size_t i=0UL; i<(~sm).rows(); ++i )
3601  if( !isDefault<RF>( (~sm)(i,j) ) )
3602  return false;
3603  }
3604 
3605  return true;
3606 }
3608 //*************************************************************************************************
3609 
3610 
3611 //*************************************************************************************************
3637 template< bool RF // Relaxation flag
3638  , typename MT // Type of the sparse matrix
3639  , AlignmentFlag AF // Alignment flag
3640  , bool SO // Storage order
3641  , size_t... CSAs > // Compile time submatrix arguments
3642 inline bool isDefault( const Submatrix<MT,AF,SO,false,CSAs...>& sm )
3643 {
3644  using blaze::isDefault;
3645 
3646  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
3647 
3648  for( size_t i=0UL; i<iend; ++i ) {
3649  for( auto element=sm.cbegin(i); element!=sm.cend(i); ++element )
3650  if( !isDefault<RF>( element->value() ) ) return false;
3651  }
3652 
3653  return true;
3654 }
3656 //*************************************************************************************************
3657 
3658 
3659 //*************************************************************************************************
3678 template< typename MT // Type of the matrix
3679  , AlignmentFlag AF // Alignment flag
3680  , bool SO // Storage order
3681  , bool DF // Density flag
3682  , size_t... CSAs > // Compile time submatrix arguments
3683 inline bool isIntact( const Submatrix<MT,AF,SO,DF,CSAs...>& sm ) noexcept
3684 {
3685  return ( sm.row() + sm.rows() <= sm.operand().rows() &&
3686  sm.column() + sm.columns() <= sm.operand().columns() &&
3687  isIntact( sm.operand() ) );
3688 }
3690 //*************************************************************************************************
3691 
3692 
3693 //*************************************************************************************************
3714 template< typename MT // Type of the matrix
3715  , AlignmentFlag AF // Alignment flag
3716  , bool SO // Storage order
3717  , bool DF // Density flag
3718  , size_t... CSAs > // Compile time submatrix arguments
3719 inline bool isSymmetric( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3720 {
3721  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3722 
3723  if( IsSymmetric_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3724  return true;
3725  else return isSymmetric( static_cast<const BaseType&>( sm ) );
3726 }
3728 //*************************************************************************************************
3729 
3730 
3731 //*************************************************************************************************
3752 template< typename MT // Type of the matrix
3753  , AlignmentFlag AF // Alignment flag
3754  , bool SO // Storage order
3755  , bool DF // Density flag
3756  , size_t... CSAs > // Compile time submatrix arguments
3757 inline bool isHermitian( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3758 {
3759  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3760 
3761  if( IsHermitian_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3762  return true;
3763  else return isHermitian( static_cast<const BaseType&>( sm ) );
3764 }
3766 //*************************************************************************************************
3767 
3768 
3769 //*************************************************************************************************
3800 template< typename MT // Type of the matrix
3801  , AlignmentFlag AF // Alignment flag
3802  , bool SO // Storage order
3803  , bool DF // Density flag
3804  , size_t... CSAs > // Compile time submatrix arguments
3805 inline bool isLower( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3806 {
3807  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3808 
3809  if( IsLower_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3810  return true;
3811  else return isLower( static_cast<const BaseType&>( sm ) );
3812 }
3814 //*************************************************************************************************
3815 
3816 
3817 //*************************************************************************************************
3847 template< typename MT // Type of the matrix
3848  , AlignmentFlag AF // Alignment flag
3849  , bool SO // Storage order
3850  , bool DF // Density flag
3851  , size_t... CSAs > // Compile time submatrix arguments
3852 inline bool isUniLower( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3853 {
3854  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3855 
3856  if( IsUniLower_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3857  return true;
3858  else return isUniLower( static_cast<const BaseType&>( sm ) );
3859 }
3861 //*************************************************************************************************
3862 
3863 
3864 //*************************************************************************************************
3894 template< typename MT // Type of the matrix
3895  , AlignmentFlag AF // Alignment flag
3896  , bool SO // Storage order
3897  , bool DF // Density flag
3898  , size_t... CSAs > // Compile time submatrix arguments
3899 inline bool isStrictlyLower( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3900 {
3901  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3902 
3903  if( IsStrictlyLower_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3904  return true;
3905  else return isStrictlyLower( static_cast<const BaseType&>( sm ) );
3906 }
3908 //*************************************************************************************************
3909 
3910 
3911 //*************************************************************************************************
3942 template< typename MT // Type of the matrix
3943  , AlignmentFlag AF // Alignment flag
3944  , bool SO // Storage order
3945  , bool DF // Density flag
3946  , size_t... CSAs > // Compile time submatrix arguments
3947 inline bool isUpper( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3948 {
3949  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3950 
3951  if( IsUpper_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3952  return true;
3953  else return isUpper( static_cast<const BaseType&>( sm ) );
3954 }
3956 //*************************************************************************************************
3957 
3958 
3959 //*************************************************************************************************
3989 template< typename MT // Type of the matrix
3990  , AlignmentFlag AF // Alignment flag
3991  , bool SO // Storage order
3992  , bool DF // Density flag
3993  , size_t... CSAs > // Compile time submatrix arguments
3994 inline bool isUniUpper( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3995 {
3996  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
3997 
3998  if( IsUniUpper_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
3999  return true;
4000  else return isUniUpper( static_cast<const BaseType&>( sm ) );
4001 }
4003 //*************************************************************************************************
4004 
4005 
4006 //*************************************************************************************************
4036 template< typename MT // Type of the matrix
4037  , AlignmentFlag AF // Alignment flag
4038  , bool SO // Storage order
4039  , bool DF // Density flag
4040  , size_t... CSAs > // Compile time submatrix arguments
4041 inline bool isStrictlyUpper( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
4042 {
4043  using BaseType = BaseType_t< Submatrix<MT,AF,SO,DF,CSAs...> >;
4044 
4045  if( IsStrictlyUpper_v<MT> && sm.row() == sm.column() && sm.rows() == sm.columns() )
4046  return true;
4047  else return isStrictlyUpper( static_cast<const BaseType&>( sm ) );
4048 }
4050 //*************************************************************************************************
4051 
4052 
4053 //*************************************************************************************************
4066 template< typename MT // Type of the matrix
4067  , AlignmentFlag AF // Alignment flag
4068  , bool SO // Storage order
4069  , bool DF // Density flag
4070  , size_t... CSAs > // Compile time submatrix arguments
4071 inline bool isSame( const Submatrix<MT,AF,SO,DF,CSAs...>& a, const Matrix<MT,SO>& b ) noexcept
4072 {
4073  return ( isSame( a.operand(), ~b ) &&
4074  ( a.rows() == (~b).rows() ) &&
4075  ( a.columns() == (~b).columns() ) );
4076 }
4078 //*************************************************************************************************
4079 
4080 
4081 //*************************************************************************************************
4094 template< typename MT // Type of the matrix
4095  , bool SO // Storage order
4096  , AlignmentFlag AF // Alignment flag
4097  , bool DF // Density flag
4098  , size_t... CSAs > // Compile time submatrix arguments
4099 inline bool isSame( const Matrix<MT,SO>& a, const Submatrix<MT,AF,SO,DF,CSAs...>& b ) noexcept
4100 {
4101  return ( isSame( ~a, b.operand() ) &&
4102  ( (~a).rows() == b.rows() ) &&
4103  ( (~a).columns() == b.columns() ) );
4104 }
4106 //*************************************************************************************************
4107 
4108 
4109 //*************************************************************************************************
4122 template< typename MT1 // Type of the matrix of the left-hand side submatrix
4123  , AlignmentFlag AF1 // Alignment flag of the left-hand side submatrix
4124  , bool SO1 // Storage order of the left-hand side submatrix
4125  , bool DF1 // Density flag of the left-hand side submatrix
4126  , size_t... CSAs1 // Compile time submatrix arguments of the left-hand side submatrix
4127  , typename MT2 // Type of the matrix of the right-hand side submatrix
4128  , AlignmentFlag AF2 // Alignment flag of the right-hand side submatrix
4129  , bool SO2 // Storage order of the right-hand side submatrix
4130  , bool DF2 // Density flag of the right-hand side submatrix
4131  , size_t... CSAs2 > // Compile time submatrix arguments of the right-hand side submatrix
4132 inline bool isSame( const Submatrix<MT1,AF1,SO1,DF1,CSAs1...>& a,
4133  const Submatrix<MT2,AF2,SO2,DF2,CSAs2...>& b ) noexcept
4134 {
4135  return ( isSame( a.operand(), b.operand() ) &&
4136  ( a.row() == b.row() ) && ( a.column() == b.column() ) &&
4137  ( a.rows() == b.rows() ) && ( a.columns() == b.columns() ) );
4138 }
4140 //*************************************************************************************************
4141 
4142 
4143 //*************************************************************************************************
4182 template< InversionFlag IF // Inversion algorithm
4183  , typename MT // Type of the dense matrix
4184  , AlignmentFlag AF // Alignment flag
4185  , bool SO // Storage order
4186  , size_t... CSAs > // Compile time submatrix arguments
4187 inline auto invert( Submatrix<MT,AF,SO,true,CSAs...>& sm )
4188  -> DisableIf_t< HasMutableDataAccess_v<MT> >
4189 {
4190  using RT = ResultType_t< Submatrix<MT,AF,SO,true,CSAs...> >;
4191 
4194 
4195  RT tmp( sm );
4196  invert<IF>( tmp );
4197  sm = tmp;
4198 }
4200 //*************************************************************************************************
4201 
4202 
4203 //*************************************************************************************************
4219 template< typename MT // Type of the matrix
4220  , AlignmentFlag AF // Alignment flag
4221  , bool SO // Storage order
4222  , bool DF // Density flag
4223  , size_t... CSAs // Compile time submatrix arguments
4224  , typename ET > // Type of the element
4225 inline bool trySet( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4226 {
4227  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4228  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4229 
4230  return trySet( sm.operand(), sm.row()+i, sm.column()+j, value );
4231 }
4233 //*************************************************************************************************
4234 
4235 
4236 //*************************************************************************************************
4252 template< typename MT // Type of the matrix
4253  , AlignmentFlag AF // Alignment flag
4254  , bool SO // Storage order
4255  , bool DF // Density flag
4256  , size_t... CSAs // Compile time submatrix arguments
4257  , typename ET > // Type of the element
4258 inline bool tryAdd( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4259 {
4260  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4261  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4262 
4263  return tryAdd( sm.operand(), sm.row()+i, sm.column()+j, value );
4264 }
4266 //*************************************************************************************************
4267 
4268 
4269 //*************************************************************************************************
4285 template< typename MT // Type of the matrix
4286  , AlignmentFlag AF // Alignment flag
4287  , bool SO // Storage order
4288  , bool DF // Density flag
4289  , size_t... CSAs // Compile time submatrix arguments
4290  , typename ET > // Type of the element
4291 inline bool trySub( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4292 {
4293  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4294  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4295 
4296  return trySub( sm.operand(), sm.row()+i, sm.column()+j, value );
4297 }
4299 //*************************************************************************************************
4300 
4301 
4302 //*************************************************************************************************
4318 template< typename MT // Type of the matrix
4319  , AlignmentFlag AF // Alignment flag
4320  , bool SO // Storage order
4321  , bool DF // Density flag
4322  , size_t... CSAs // Compile time submatrix arguments
4323  , typename ET > // Type of the element
4324 inline bool tryMult( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4325 {
4326  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4327  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4328 
4329  return tryMult( sm.operand(), sm.row()+i, sm.column()+j, value );
4330 }
4332 //*************************************************************************************************
4333 
4334 
4335 //*************************************************************************************************
4353 template< typename MT // Type of the matrix
4354  , AlignmentFlag AF // Alignment flag
4355  , bool SO // Storage order
4356  , bool DF // Density flag
4357  , size_t... CSAs // Compile time submatrix arguments
4358  , typename ET > // Type of the element
4360  tryMult( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t row, size_t column, size_t m, size_t n, const ET& value )
4361 {
4363 
4364  BLAZE_INTERNAL_ASSERT( row <= (~sm).rows(), "Invalid row access index" );
4365  BLAZE_INTERNAL_ASSERT( column <= (~sm).columns(), "Invalid column access index" );
4366  BLAZE_INTERNAL_ASSERT( row + m <= (~sm).rows(), "Invalid number of rows" );
4367  BLAZE_INTERNAL_ASSERT( column + n <= (~sm).columns(), "Invalid number of columns" );
4368 
4369  return tryMult( sm.operand(), sm.row()+row, sm.column(), m, n, value );
4370 }
4372 //*************************************************************************************************
4373 
4374 
4375 //*************************************************************************************************
4391 template< typename MT // Type of the matrix
4392  , AlignmentFlag AF // Alignment flag
4393  , bool SO // Storage order
4394  , bool DF // Density flag
4395  , size_t... CSAs // Compile time submatrix arguments
4396  , typename ET > // Type of the element
4397 inline bool tryDiv( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4398 {
4399  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4400  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4401 
4402  return tryDiv( sm.operand(), sm.row()+i, sm.column()+j, value );
4403 }
4405 //*************************************************************************************************
4406 
4407 
4408 //*************************************************************************************************
4426 template< typename MT // Type of the matrix
4427  , AlignmentFlag AF // Alignment flag
4428  , bool SO // Storage order
4429  , bool DF // Density flag
4430  , size_t... CSAs // Compile time submatrix arguments
4431  , typename ET > // Type of the element
4433  tryDiv( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t row, size_t column, size_t m, size_t n, const ET& value )
4434 {
4436 
4437  BLAZE_INTERNAL_ASSERT( row <= (~sm).rows(), "Invalid row access index" );
4438  BLAZE_INTERNAL_ASSERT( column <= (~sm).columns(), "Invalid column access index" );
4439  BLAZE_INTERNAL_ASSERT( row + m <= (~sm).rows(), "Invalid number of rows" );
4440  BLAZE_INTERNAL_ASSERT( column + n <= (~sm).columns(), "Invalid number of columns" );
4441 
4442  return tryDiv( sm.operand(), sm.row()+row, sm.column(), m, n, value );
4443 }
4445 //*************************************************************************************************
4446 
4447 
4448 //*************************************************************************************************
4464 template< typename MT // Type of the matrix
4465  , AlignmentFlag AF // Alignment flag
4466  , bool SO // Storage order
4467  , bool DF // Density flag
4468  , size_t... CSAs // Compile time submatrix arguments
4469  , typename VT // Type of the right-hand side vector
4470  , bool TF > // Transpose flag of the right-hand side vector
4471 inline bool tryAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4472  const Vector<VT,TF>& rhs, size_t row, size_t column )
4473 {
4474  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4475  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4476  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4477  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4478 
4479  return tryAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4480 }
4482 //*************************************************************************************************
4483 
4484 
4485 //*************************************************************************************************
4502 template< typename MT // Type of the matrix
4503  , AlignmentFlag AF // Alignment flag
4504  , bool SO // Storage order
4505  , bool DF // Density flag
4506  , size_t... CSAs // Compile time submatrix arguments
4507  , typename VT // Type of the right-hand side vector
4508  , bool TF > // Transpose flag of the right-hand side vector
4509 inline bool tryAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4510  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4511 {
4512  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4513  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4514  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4515  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4516 
4517  return tryAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4518  lhs.row() + row, lhs.column() + column );
4519 }
4521 //*************************************************************************************************
4522 
4523 
4524 //*************************************************************************************************
4540 template< typename MT1 // Type of the matrix
4541  , AlignmentFlag AF // Alignment flag
4542  , bool SO1 // Storage order
4543  , bool DF // Density flag
4544  , size_t... CSAs // Compile time submatrix arguments
4545  , typename MT2 // Type of the right-hand side matrix
4546  , bool SO2 > // Storage order of the right-hand side matrix
4547 inline bool tryAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4548  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4549 {
4550  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4551  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4552  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4553  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4554 
4555  return tryAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4556 }
4558 //*************************************************************************************************
4559 
4560 
4561 //*************************************************************************************************
4577 template< typename MT // Type of the matrix
4578  , AlignmentFlag AF // Alignment flag
4579  , bool SO // Storage order
4580  , bool DF // Density flag
4581  , size_t... CSAs // Compile time submatrix arguments
4582  , typename VT // Type of the right-hand side vector
4583  , bool TF > // Transpose flag of the right-hand side vector
4584 inline bool tryAddAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4585  const Vector<VT,TF>& rhs, size_t row, size_t column )
4586 {
4587  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4588  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4589  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4590  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4591 
4592  return tryAddAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4593 }
4595 //*************************************************************************************************
4596 
4597 
4598 //*************************************************************************************************
4616 template< typename MT // Type of the matrix
4617  , AlignmentFlag AF // Alignment flag
4618  , bool SO // Storage order
4619  , bool DF // Density flag
4620  , size_t... CSAs // Compile time submatrix arguments
4621  , typename VT // Type of the right-hand side vector
4622  , bool TF > // Transpose flag of the right-hand side vector
4623 inline bool tryAddAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4624  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4625 {
4626  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4627  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4628  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4629  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4630 
4631  return tryAddAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4632  lhs.row() + row, lhs.column() + column );
4633 }
4635 //*************************************************************************************************
4636 
4637 
4638 //*************************************************************************************************
4654 template< typename MT1 // Type of the matrix
4655  , AlignmentFlag AF // Alignment flag
4656  , bool SO1 // Storage order
4657  , bool DF // Density flag
4658  , size_t... CSAs // Compile time submatrix arguments
4659  , typename MT2 // Type of the right-hand side matrix
4660  , bool SO2 > // Storage order of the right-hand side matrix
4661 inline bool tryAddAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4662  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4663 {
4664  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4665  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4666  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4667  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4668 
4669  return tryAddAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4670 }
4672 //*************************************************************************************************
4673 
4674 
4675 //*************************************************************************************************
4691 template< typename MT // Type of the matrix
4692  , AlignmentFlag AF // Alignment flag
4693  , bool SO // Storage order
4694  , bool DF // Density flag
4695  , size_t... CSAs // Compile time submatrix arguments
4696  , typename VT // Type of the right-hand side vector
4697  , bool TF > // Transpose flag of the right-hand side vector
4698 inline bool trySubAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4699  const Vector<VT,TF>& rhs, size_t row, size_t column )
4700 {
4701  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4702  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4703  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4704  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4705 
4706  return trySubAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4707 }
4709 //*************************************************************************************************
4710 
4711 
4712 //*************************************************************************************************
4730 template< typename MT // Type of the matrix
4731  , AlignmentFlag AF // Alignment flag
4732  , bool SO // Storage order
4733  , bool DF // Density flag
4734  , size_t... CSAs // Compile time submatrix arguments
4735  , typename VT // Type of the right-hand side vector
4736  , bool TF > // Transpose flag of the right-hand side vector
4737 inline bool trySubAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4738  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4739 {
4740  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4741  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4742  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4743  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4744 
4745  return trySubAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4746  lhs.row() + row, lhs.column() + column );
4747 }
4749 //*************************************************************************************************
4750 
4751 
4752 //*************************************************************************************************
4768 template< typename MT1 // Type of the matrix
4769  , AlignmentFlag AF // Alignment flag
4770  , bool SO1 // Storage order
4771  , bool DF // Density flag
4772  , size_t... CSAs // Compile time submatrix arguments
4773  , typename MT2 // Type of the right-hand side matrix
4774  , bool SO2 > // Storage order of the right-hand side matrix
4775 inline bool trySubAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4776  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4777 {
4778  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4779  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4780  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4781  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4782 
4783  return trySubAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4784 }
4786 //*************************************************************************************************
4787 
4788 
4789 //*************************************************************************************************
4805 template< typename MT // Type of the matrix
4806  , AlignmentFlag AF // Alignment flag
4807  , bool SO // Storage order
4808  , bool DF // Density flag
4809  , size_t... CSAs // Compile time submatrix arguments
4810  , typename VT // Type of the right-hand side vector
4811  , bool TF > // Transpose flag of the right-hand side vector
4812 inline bool tryMultAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4813  const Vector<VT,TF>& rhs, size_t row, size_t column )
4814 {
4815  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4816  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4817  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4818  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4819 
4820  return tryMultAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4821 }
4823 //*************************************************************************************************
4824 
4825 
4826 //*************************************************************************************************
4844 template< typename MT // Type of the matrix
4845  , AlignmentFlag AF // Alignment flag
4846  , bool SO // Storage order
4847  , bool DF // Density flag
4848  , size_t... CSAs // Compile time submatrix arguments
4849  , typename VT // Type of the right-hand side vector
4850  , bool TF > // Transpose flag of the right-hand side vector
4851 inline bool tryMultAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4852  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4853 {
4854  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4855  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4856  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4857  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4858 
4859  return tryMultAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4860  lhs.row() + row, lhs.column() + column );
4861 }
4863 //*************************************************************************************************
4864 
4865 
4866 //*************************************************************************************************
4882 template< typename MT1 // Type of the matrix
4883  , AlignmentFlag AF // Alignment flag
4884  , bool SO1 // Storage order
4885  , bool DF // Density flag
4886  , size_t... CSAs // Compile time submatrix arguments
4887  , typename MT2 // Type of the right-hand side matrix
4888  , bool SO2 > // Storage order of the right-hand side matrix
4889 inline bool trySchurAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4890  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4891 {
4892  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4893  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4894  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4895  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4896 
4897  return trySchurAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4898 }
4900 //*************************************************************************************************
4901 
4902 
4903 //*************************************************************************************************
4919 template< typename MT // Type of the matrix
4920  , AlignmentFlag AF // Alignment flag
4921  , bool SO // Storage order
4922  , bool DF // Density flag
4923  , size_t... CSAs // Compile time submatrix arguments
4924  , typename VT // Type of the right-hand side vector
4925  , bool TF > // Transpose flag of the right-hand side vector
4926 inline bool tryDivAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4927  const Vector<VT,TF>& rhs, size_t row, size_t column )
4928 {
4929  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4930  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4931  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4932  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4933 
4934  return tryDivAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4935 }
4937 //*************************************************************************************************
4938 
4939 
4940 //*************************************************************************************************
4958 template< typename MT // Type of the matrix
4959  , AlignmentFlag AF // Alignment flag
4960  , bool SO // Storage order
4961  , bool DF // Density flag
4962  , size_t... CSAs // Compile time submatrix arguments
4963  , typename VT // Type of the right-hand side vector
4964  , bool TF > // Transpose flag of the right-hand side vector
4965 inline bool tryDivAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4966  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4967 {
4968  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4969  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4970  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4971  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4972 
4973  return tryDivAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4974  lhs.row() + row, lhs.column() + column );
4975 }
4977 //*************************************************************************************************
4978 
4979 
4980 //*************************************************************************************************
4995 template< typename MT // Type of the matrix
4996  , AlignmentFlag AF // Alignment flag
4997  , bool SO // Storage order
4998  , bool DF // Density flag
4999  , size_t I // Index of the first row
5000  , size_t J // Index of the first column
5001  , size_t M // Number of rows
5002  , size_t N > // Number of columns
5003 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF,I,J,M,N>& dm )
5004 {
5005  return submatrix<AF,I,J,M,N>( derestrict( dm.operand() ), unchecked );
5006 }
5008 //*************************************************************************************************
5009 
5010 
5011 //*************************************************************************************************
5026 template< typename MT // Type of the matrix
5027  , AlignmentFlag AF // Alignment flag
5028  , bool SO // Storage order
5029  , bool DF // Density flag
5030  , size_t I // Index of the first row
5031  , size_t J // Index of the first column
5032  , size_t M // Number of rows
5033  , size_t N > // Number of columns
5034 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF,I,J,M,N>&& dm )
5035 {
5036  return submatrix<AF,I,J,M,N>( derestrict( dm.operand() ), unchecked );
5037 }
5039 //*************************************************************************************************
5040 
5041 
5042 //*************************************************************************************************
5057 template< typename MT // Type of the matrix
5058  , AlignmentFlag AF // Alignment flag
5059  , bool SO // Storage order
5060  , bool DF > // Density flag
5061 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF>& dm )
5062 {
5063  return submatrix<AF>( derestrict( dm.operand() ), dm.row(), dm.column(), dm.rows(), dm.columns(), unchecked );
5064 }
5066 //*************************************************************************************************
5067 
5068 
5069 //*************************************************************************************************
5084 template< typename MT // Type of the matrix
5085  , AlignmentFlag AF // Alignment flag
5086  , bool SO // Storage order
5087  , bool DF > // Density flag
5088 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF>&& dm )
5089 {
5090  return submatrix<AF>( derestrict( dm.operand() ), dm.row(), dm.column(), dm.rows(), dm.columns(), unchecked );
5091 }
5093 //*************************************************************************************************
5094 
5095 
5096 
5097 
5098 //=================================================================================================
5099 //
5100 // SIZE SPECIALIZATIONS
5101 //
5102 //=================================================================================================
5103 
5104 //*************************************************************************************************
5106 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5107 struct Size< Submatrix<MT,AF,SO,DF,I,J,M,N>, 0UL >
5108  : public PtrdiffT<M>
5109 {};
5110 
5111 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5112 struct Size< Submatrix<MT,AF,SO,DF,I,J,M,N>, 1UL >
5113  : public PtrdiffT<N>
5114 {};
5116 //*************************************************************************************************
5117 
5118 
5119 
5120 
5121 //=================================================================================================
5122 //
5123 // MAXSIZE SPECIALIZATIONS
5124 //
5125 //=================================================================================================
5126 
5127 //*************************************************************************************************
5129 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5130 struct MaxSize< Submatrix<MT,AF,SO,DF,I,J,M,N>, 0UL >
5131  : public PtrdiffT<M>
5132 {};
5133 
5134 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5135 struct MaxSize< Submatrix<MT,AF,SO,DF,I,J,M,N>, 1UL >
5136  : public PtrdiffT<N>
5137 {};
5139 //*************************************************************************************************
5140 
5141 
5142 
5143 
5144 //=================================================================================================
5145 //
5146 // ISRESTRICTED SPECIALIZATIONS
5147 //
5148 //=================================================================================================
5149 
5150 //*************************************************************************************************
5152 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs >
5153 struct IsRestricted< Submatrix<MT,AF,SO,DF,CSAs...> >
5154  : public IsRestricted<MT>
5155 {};
5157 //*************************************************************************************************
5158 
5159 
5160 
5161 
5162 //=================================================================================================
5163 //
5164 // HASCONSTDATAACCESS SPECIALIZATIONS
5165 //
5166 //=================================================================================================
5167 
5168 //*************************************************************************************************
5170 template< typename MT, AlignmentFlag AF, bool SO, size_t... CSAs >
5171 struct HasConstDataAccess< Submatrix<MT,AF,SO,true,CSAs...> >
5172  : public HasConstDataAccess<MT>
5173 {};
5175 //*************************************************************************************************
5176 
5177 
5178 
5179 
5180 //=================================================================================================
5181 //
5182 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5183 //
5184 //=================================================================================================
5185 
5186 //*************************************************************************************************
5188 template< typename MT, AlignmentFlag AF, bool SO, size_t... CSAs >
5189 struct HasMutableDataAccess< Submatrix<MT,AF,SO,true,CSAs...> >
5190  : public HasMutableDataAccess<MT>
5191 {};
5193 //*************************************************************************************************
5194 
5195 
5196 
5197 
5198 //=================================================================================================
5199 //
5200 // ISALIGNED SPECIALIZATIONS
5201 //
5202 //=================================================================================================
5203 
5204 //*************************************************************************************************
5206 template< typename MT, bool SO, size_t... CSAs >
5207 struct IsAligned< Submatrix<MT,aligned,SO,true,CSAs...> >
5208  : public TrueType
5209 {};
5211 //*************************************************************************************************
5212 
5213 
5214 
5215 
5216 //=================================================================================================
5217 //
5218 // ISCONTIGUOUS SPECIALIZATIONS
5219 //
5220 //=================================================================================================
5221 
5222 //*************************************************************************************************
5224 template< typename MT, AlignmentFlag AF, bool SO, size_t... CSAs >
5225 struct IsContiguous< Submatrix<MT,AF,SO,true,CSAs...> >
5226  : public IsContiguous<MT>
5227 {};
5229 //*************************************************************************************************
5230 
5231 
5232 
5233 
5234 //=================================================================================================
5235 //
5236 // ISSYMMETRIC SPECIALIZATIONS
5237 //
5238 //=================================================================================================
5239 
5240 //*************************************************************************************************
5242 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5243 struct IsSymmetric< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5244  : public BoolConstant< ( IsSymmetric_v<MT> && I == J && M == N ) >
5245 {};
5247 //*************************************************************************************************
5248 
5249 
5250 
5251 
5252 //=================================================================================================
5253 //
5254 // ISHERMITIAN SPECIALIZATIONS
5255 //
5256 //=================================================================================================
5257 
5258 //*************************************************************************************************
5260 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5261 struct IsHermitian< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5262  : public BoolConstant< ( IsHermitian_v<MT> && I == J && M == N ) >
5263 {};
5265 //*************************************************************************************************
5266 
5267 
5268 
5269 
5270 //=================================================================================================
5271 //
5272 // ISLOWER SPECIALIZATIONS
5273 //
5274 //=================================================================================================
5275 
5276 //*************************************************************************************************
5278 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5279 struct IsLower< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5280  : public BoolConstant< ( IsLower_v<MT> && I == J && M == N ) ||
5281  ( IsStrictlyLower_v<MT> && I == J+1UL && M == N ) >
5282 {};
5284 //*************************************************************************************************
5285 
5286 
5287 
5288 
5289 //=================================================================================================
5290 //
5291 // ISUNILOWER SPECIALIZATIONS
5292 //
5293 //=================================================================================================
5294 
5295 //*************************************************************************************************
5297 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5298 struct IsUniLower< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5299  : public BoolConstant< ( IsUniLower_v<MT> && I == J && M == N ) >
5300 {};
5302 //*************************************************************************************************
5303 
5304 
5305 
5306 
5307 //=================================================================================================
5308 //
5309 // ISSTRICTLYLOWER SPECIALIZATIONS
5310 //
5311 //=================================================================================================
5312 
5313 //*************************************************************************************************
5315 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5316 struct IsStrictlyLower< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5317  : public BoolConstant< ( IsLower_v<MT> && I < J && M == N ) ||
5318  ( IsStrictlyLower_v<MT> && I == J && M == N ) >
5319 {};
5321 //*************************************************************************************************
5322 
5323 
5324 
5325 
5326 //=================================================================================================
5327 //
5328 // ISUPPER SPECIALIZATIONS
5329 //
5330 //=================================================================================================
5331 
5332 //*************************************************************************************************
5334 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5335 struct IsUpper< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5336  : public BoolConstant< ( IsUpper_v<MT> && I == J && M == N ) ||
5337  ( IsStrictlyUpper_v<MT> && I+1UL == J && M == N ) >
5338 {};
5340 //*************************************************************************************************
5341 
5342 
5343 
5344 
5345 //=================================================================================================
5346 //
5347 // ISUNIUPPER SPECIALIZATIONS
5348 //
5349 //=================================================================================================
5350 
5351 //*************************************************************************************************
5353 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5354 struct IsUniUpper< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5355  : public BoolConstant< ( IsUniUpper_v<MT> && I == J && M == N ) >
5356 {};
5358 //*************************************************************************************************
5359 
5360 
5361 
5362 
5363 //=================================================================================================
5364 //
5365 // ISSTRICTLYUPPER SPECIALIZATIONS
5366 //
5367 //=================================================================================================
5368 
5369 //*************************************************************************************************
5371 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5372 struct IsStrictlyUpper< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5373  : public BoolConstant< ( IsUpper_v<MT> && I > J && M == N ) ||
5374  ( IsStrictlyUpper_v<MT> && I == J && M == N ) >
5375 {};
5377 //*************************************************************************************************
5378 
5379 } // namespace blaze
5380 
5381 #endif
decltype(auto) subvector(Vector< VT, TF > &, RSAs...)
Creating a view on a specific subvector of the given vector.
Definition: Subvector.h:329
AlignmentFlag
Alignment flag for (un-)aligned vectors and matrices.Via these flags it is possible to specify subvec...
Definition: AlignmentFlag.h:62
#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.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Headerfile for the generic min algorithm.
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
Header file for the implementation of the RowData class template.
#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
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
#define BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS(T)
Constraint on the data type.In case the given data type T does not provide low-level data access to m...
Definition: MutableDataAccess.h:61
bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:992
Header file for basic type definitions.
Header file for the MatReduceExpr base class.
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 serial shim.
Header file for the MatTransExpr base class.
Header file for the dense matrix inversion flags.
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1092
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
Header file for the MatEvalExpr base class.
typename RemoveReference< T >::Type RemoveReference_t
Auxiliary alias declaration for the RemoveReference type trait.The RemoveReference_t alias declaratio...
Definition: RemoveReference.h:95
Header file for the MatMatMultExpr base class.
constexpr bool IsUpper_v
Auxiliary variable template for the IsUpper type trait.The IsUpper_v variable template provides a con...
Definition: IsUpper.h:174
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
#define BLAZE_STATIC_ASSERT_MSG(expr, msg)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:123
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
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
void invert(const HermitianProxy< MT > &proxy)
In-place inversion of the represented element.
Definition: HermitianProxy.h:775
Submatrix specialization for dense matrices.
Header file for the MatMapExpr base class.
Header file for the implementation of the Subvector view.
decltype(auto) reduce(const DenseMatrix< MT, SO > &dm, OP op)
Performs a custom reduction operation on the given dense matrix.
Definition: DMatReduceExpr.h:2016
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the SmallArray implementation.
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
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Compile time assertion.
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1147
Header file for the implementation of the Submatrix base template.
Header file for the MatMatSubExpr base class.
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:139
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
Header file for the TransposeFlag type trait.
decltype(auto) eval(const DenseMatrix< MT, SO > &dm)
Forces the evaluation of the given dense matrix expression dm.
Definition: DMatEvalExpr.h:786
constexpr bool IsStrictlyLower_v
Auxiliary variable template for the IsStrictlyLower type trait.The IsStrictlyLower_v variable templat...
Definition: IsStrictlyLower.h:172
Submatrix specialization for sparse matrices.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1179
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
Constraint on the data type.
Constraint on the data type.
Header file for the MatSerialExpr base class.
Header file for the VecTVecMultExpr base class.
decltype(auto) submatrix(Matrix< MT, SO > &, RSAs...)
Creating a view on a specific submatrix of the given matrix.
Definition: Submatrix.h:360
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:611
decltype(auto) band(Matrix< MT, SO > &matrix, RBAs... args)
Creating a view on a specific band of the given matrix.
Definition: Band.h:135
Flag for aligned vectors and matrices.
Definition: AlignmentFlag.h:65
Header file for the HasConstDataAccess type trait.
IntegralConstant< ptrdiff_t, N > PtrdiffT
Compile time integral constant wrapper for ptrdiff_t.The PtrdiffT class template represents an integr...
Definition: PtrdiffT.h:72
Header file for the DeclExpr base class.
Header file for the Matrix base class.
Header file for the PtrdiffT class template.
constexpr size_t columnwise
Reduction flag for column-wise reduction operations.
Definition: ReductionFlag.h:90
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1446
decltype(subsequence< Is... >(shift< Offset >(make_index_sequence< N >()))) make_shifted_index_subsequence
Auxiliary alias declaration for the setup of shifted index subsequences.The make_shifted_index_subseq...
Definition: IntegerSequence.h:243
Header file for the MatScalarMultExpr base class.
Header file for run time assertion macros.
Header file for the Unique class template.
Header file for the IsContiguous type trait.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
Header file for the SchurExpr base class.
decltype(auto) expand(const DenseVector< VT, TF > &dv, size_t expansion)
Expansion of the given dense vector.
Definition: DVecExpandExpr.h:739
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
constexpr bool IsStrictlyUpper_v
Auxiliary variable template for the IsStrictlyUpper type trait.The IsStrictlyUpper_v variable templat...
Definition: IsStrictlyUpper.h:172
constexpr bool IsLower_v
Auxiliary variable template for the IsLower type trait.The IsLower_v variable template provides a con...
Definition: IsLower.h:174
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
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.
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:109
typename T::VectorType VectorType_t
Alias declaration for nested VectorType type definitions.The VectorType_t alias declaration provides ...
Definition: Aliases.h:510
Header file for the TVecMatMultExpr base class.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
Header file for the HasMutableDataAccess type trait.
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
Header file for the MatMatAddExpr base class.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:101
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 RemoveReference type trait.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Header file for the VecExpandExpr base class.
typename T::BaseType BaseType_t
Alias declaration for nested BaseType type definitions.The BaseType_t alias declaration provides a co...
Definition: Aliases.h:70
constexpr size_t rowwise
Reduction flag for row-wise reduction operations.
Definition: ReductionFlag.h:70
Header file for the MatMatMapExpr base class.
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:1359
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
Header file for the IsUpper type trait.
Header file for the implementation of the ColumnData class template.
Header file for the MatScalarDivExpr base class.
Header file for the MatVecMultExpr base class.
Header file for the IsHermitian type trait.
Header file for the IsRestricted type trait.
Header file for the Size type trait.
InversionFlag
Inversion flag.The InversionFlag type enumeration represents the different types of matrix inversion ...
Definition: InversionFlag.h:101
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the reduction flags.
Header file for the TrueType type/value trait base class.
Header file for the function trace functionality.
decltype(auto) map(const DenseMatrix< MT1, SO > &lhs, const DenseMatrix< MT2, SO > &rhs, OP op)
Evaluates the given binary operation on each single element of the dense matrices lhs and rhs...
Definition: DMatDMatMapExpr.h:1110