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>
86 #include <blaze/math/views/Check.h>
95 #include <blaze/util/Assert.h>
97 #include <blaze/util/DisableIf.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 
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<MT1>::value )
980  ?( ( !AF && IsStrictlyUpper<MT1>::value )
981  ?( sd.row() + 1UL )
982  :( sd.row() ) )
983  :( 0UL )
984  , ( IsLower<MT2>::value )
985  ?( ( !AF && IsStrictlyLower<MT2>::value )
986  ?( sd.column() + 1UL )
987  :( sd.column() ) )
988  :( 0UL ) ) );
989  const size_t end( min( ( IsLower<MT1>::value )
990  ?( ( IsStrictlyLower<MT1>::value && sd.rows() > 0UL )
991  ?( sd.row() + sd.rows() - 1UL )
992  :( sd.row() + sd.rows() ) )
993  :( left.columns() )
994  , ( IsUpper<MT2>::value )
995  ?( ( IsStrictlyUpper<MT2>::value && 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 //*************************************************************************************************
1322 template< AlignmentFlag AF1 // Required alignment flag
1323  , size_t I1 // Required index of the first row
1324  , size_t J1 // Required index of the first column
1325  , size_t M1 // Required number of rows
1326  , size_t N1 // Required number of columns
1327  , typename MT // Type of the sparse submatrix
1328  , AlignmentFlag AF2 // Present alignment flag
1329  , bool SO // Storage order
1330  , bool DF // Density flag
1331  , size_t I2 // Present index of the first row
1332  , size_t J2 // Present index of the first column
1333  , size_t M2 // Present number of rows
1334  , size_t N2 // Present number of columns
1335  , typename... RSAs > // Optional submatrix arguments
1336 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF,I2,J2,M2,N2>& sm, RSAs... args )
1337 {
1339 
1340  BLAZE_STATIC_ASSERT_MSG( I1 + M1 <= M2, "Invalid submatrix specification" );
1341  BLAZE_STATIC_ASSERT_MSG( J1 + N1 <= N2, "Invalid submatrix specification" );
1342 
1343  return submatrix<AF1,I1+I2,J1+J2,M1,N1>( sm.operand(), args... );
1344 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1361 template< AlignmentFlag AF1 // Required alignment flag
1362  , size_t I1 // Required index of the first row
1363  , size_t J1 // Required index of the first column
1364  , size_t M1 // Required number of rows
1365  , size_t N1 // Required number of columns
1366  , typename MT // Type of the sparse submatrix
1367  , AlignmentFlag AF2 // Present alignment flag
1368  , bool SO // Storage order
1369  , bool DF // Density flag
1370  , size_t I2 // Present index of the first row
1371  , size_t J2 // Present index of the first column
1372  , size_t M2 // Present number of rows
1373  , size_t N2 // Present number of columns
1374  , typename... RSAs > // Optional submatrix arguments
1375 inline decltype(auto) submatrix( const Submatrix<MT,AF2,SO,DF,I2,J2,M2,N2>& sm, RSAs... args )
1376 {
1378 
1379  BLAZE_STATIC_ASSERT_MSG( I1 + M1 <= M2, "Invalid submatrix specification" );
1380  BLAZE_STATIC_ASSERT_MSG( J1 + N1 <= N2, "Invalid submatrix specification" );
1381 
1382  return submatrix<AF1,I1+I2,J1+J2,M1,N1>( sm.operand(), args... );
1383 }
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
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 I // Index of the first row
1441  , size_t J // Index of the first column
1442  , size_t M // Number of rows
1443  , size_t N // 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  , typename... RSAs > // Optional submatrix arguments
1449 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF>& sm, RSAs... args )
1450 {
1452 
1453  constexpr bool isChecked( !Contains< TypeList<RSAs...>, Unchecked >::value );
1454 
1455  if( isChecked ) {
1456  if( ( I + M > sm.rows() ) || ( J + N > sm.columns() ) ) {
1457  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1458  }
1459  }
1460  else {
1461  BLAZE_USER_ASSERT( I + M <= sm.rows() , "Invalid submatrix specification" );
1462  BLAZE_USER_ASSERT( J + N <= sm.columns(), "Invalid submatrix specification" );
1463  }
1464 
1465  return submatrix<AF1>( sm.operand(), sm.row() + I, sm.column() + J, M, N, args... );
1466 }
1468 //*************************************************************************************************
1469 
1470 
1471 //*************************************************************************************************
1484 template< AlignmentFlag AF1 // Required alignment flag
1485  , size_t I // Index of the first row
1486  , size_t J // Index of the first column
1487  , size_t M // Number of rows
1488  , size_t N // Number of columns
1489  , typename MT // Type of the sparse submatrix
1490  , AlignmentFlag AF2 // Present alignment flag
1491  , bool SO // Storage order
1492  , bool DF // Density flag
1493  , typename... RSAs > // Optional submatrix arguments
1494 inline decltype(auto) submatrix( const Submatrix<MT,AF2,SO,DF>& sm, RSAs... args )
1495 {
1497 
1498  constexpr bool isChecked( !Contains< TypeList<RSAs...>, Unchecked >::value );
1499 
1500  if( isChecked ) {
1501  if( ( I + M > sm.rows() ) || ( J + N > sm.columns() ) ) {
1502  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1503  }
1504  }
1505  else {
1506  BLAZE_USER_ASSERT( I + M <= sm.rows() , "Invalid submatrix specification" );
1507  BLAZE_USER_ASSERT( J + N <= sm.columns(), "Invalid submatrix specification" );
1508  }
1509 
1510  return submatrix<AF1>( sm.operand(), sm.row() + I, sm.column() + J, M, N, args... );
1511 }
1513 //*************************************************************************************************
1514 
1515 
1516 //*************************************************************************************************
1529 template< AlignmentFlag AF1 // Required alignment flag
1530  , size_t I // Index of the first row
1531  , size_t J // Index of the first column
1532  , size_t M // Number of rows
1533  , size_t N // Number of columns
1534  , typename MT // Type of the sparse submatrix
1535  , AlignmentFlag AF2 // Present alignment flag
1536  , bool SO // Storage order
1537  , bool DF // Density flag
1538  , typename... RSAs > // Optional submatrix arguments
1539 inline decltype(auto) submatrix( Submatrix<MT,AF2,SO,DF>&& sm, RSAs... args )
1540 {
1542 
1543  constexpr bool isChecked( !Contains< TypeList<RSAs...>, Unchecked >::value );
1544 
1545  if( isChecked ) {
1546  if( ( I + M > sm.rows() ) || ( J + N > sm.columns() ) ) {
1547  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1548  }
1549  }
1550  else {
1551  BLAZE_USER_ASSERT( I + M <= sm.rows() , "Invalid submatrix specification" );
1552  BLAZE_USER_ASSERT( J + N <= sm.columns(), "Invalid submatrix specification" );
1553  }
1554 
1555  return submatrix<AF1>( sm.operand(), sm.row() + I, sm.column() + J, M, N, args... );
1556 }
1558 //*************************************************************************************************
1559 
1560 
1561 //*************************************************************************************************
1577 template< AlignmentFlag AF1 // Required alignment flag
1578  , typename MT // Type of the sparse submatrix
1579  , AlignmentFlag AF2 // Present alignment flag
1580  , bool SO // Storage order
1581  , bool DF // Density flag
1582  , size_t... CSAs // Compile time submatrix arguments
1583  , typename... RSAs > // Optional submatrix arguments
1584 inline decltype(auto)
1585  submatrix( Submatrix<MT,AF2,SO,DF,CSAs...>& sm, size_t row, size_t column,
1586  size_t m, size_t n, RSAs... args )
1587 {
1589 
1590  constexpr bool isChecked( !Contains< TypeList<RSAs...>, Unchecked >::value );
1591 
1592  if( isChecked ) {
1593  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
1594  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1595  }
1596  }
1597  else {
1598  BLAZE_USER_ASSERT( row + m <= sm.rows() , "Invalid submatrix specification" );
1599  BLAZE_USER_ASSERT( column + n <= sm.columns(), "Invalid submatrix specification" );
1600  }
1601 
1602  return submatrix<AF1>( sm.operand(), sm.row() + row, sm.column() + column, m, n, args... );
1603 }
1605 //*************************************************************************************************
1606 
1607 
1608 //*************************************************************************************************
1625 template< AlignmentFlag AF1 // Required alignment flag
1626  , typename MT // Type of the sparse submatrix
1627  , AlignmentFlag AF2 // Present alignment flag
1628  , bool SO // Storage order
1629  , bool DF // Density flag
1630  , size_t... CSAs // Compile time submatrix arguments
1631  , typename... RSAs > // Optional submatrix arguments
1632 inline decltype(auto)
1633  submatrix( const Submatrix<MT,AF2,SO,DF,CSAs...>& sm, size_t row, size_t column,
1634  size_t m, size_t n, RSAs... args )
1635 {
1637 
1638  constexpr bool isChecked( !Contains< TypeList<RSAs...>, Unchecked >::value );
1639 
1640  if( isChecked ) {
1641  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
1642  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1643  }
1644  }
1645  else {
1646  BLAZE_USER_ASSERT( row + m <= sm.rows() , "Invalid submatrix specification" );
1647  BLAZE_USER_ASSERT( column + n <= sm.columns(), "Invalid submatrix specification" );
1648  }
1649 
1650  return submatrix<AF1>( sm.operand(), sm.row() + row, sm.column() + column, m, n, args... );
1651 }
1653 //*************************************************************************************************
1654 
1655 
1656 //*************************************************************************************************
1673 template< AlignmentFlag AF1 // Required alignment flag
1674  , typename MT // Type of the sparse submatrix
1675  , AlignmentFlag AF2 // Present alignment flag
1676  , bool SO // Storage order
1677  , bool DF // Density flag
1678  , size_t... CSAs // Compile time submatrix arguments
1679  , typename... RSAs > // Optional submatrix arguments
1680 inline decltype(auto)
1681  submatrix( Submatrix<MT,AF2,SO,DF,CSAs...>&& sm, size_t row, size_t column,
1682  size_t m, size_t n, RSAs... args )
1683 {
1685 
1686  constexpr bool isChecked( !Contains< TypeList<RSAs...>, Unchecked >::value );
1687 
1688  if( isChecked ) {
1689  if( ( row + m > sm.rows() ) || ( column + n > sm.columns() ) ) {
1690  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1691  }
1692  }
1693  else {
1694  BLAZE_USER_ASSERT( row + m <= sm.rows() , "Invalid submatrix specification" );
1695  BLAZE_USER_ASSERT( column + n <= sm.columns(), "Invalid submatrix specification" );
1696  }
1697 
1698  return submatrix<AF1>( sm.operand(), sm.row() + row, sm.column() + column, m, n, args... );
1699 }
1701 //*************************************************************************************************
1702 
1703 
1704 
1705 
1706 //=================================================================================================
1707 //
1708 // GLOBAL RESTRUCTURING FUNCTIONS (SUBVECTOR)
1709 //
1710 //=================================================================================================
1711 
1712 //*************************************************************************************************
1724 template< AlignmentFlag AF // Alignment flag
1725  , size_t... CSAs // Compile time subvector arguments
1726  , typename VT // Vector base type of the expression
1727  , typename... RSAs > // Runtime subvector arguments
1728 inline decltype(auto) subvector( const MatVecMultExpr<VT>& vector, RSAs... args )
1729 {
1731 
1733 
1734  const SubvectorData<CSAs...> sd( args... );
1735 
1736  BLAZE_DECLTYPE_AUTO( left , (~vector).leftOperand() );
1737  BLAZE_DECLTYPE_AUTO( right, (~vector).rightOperand() );
1738 
1739  const size_t column( ( IsUpper<MT>::value )
1740  ?( ( !AF && IsStrictlyUpper<MT>::value )?( sd.offset() + 1UL ):( sd.offset() ) )
1741  :( 0UL ) );
1742  const size_t n( ( IsLower<MT>::value )
1743  ?( ( IsUpper<MT>::value )?( sd.size() )
1744  :( ( IsStrictlyLower<MT>::value && sd.size() > 0UL )
1745  ?( sd.offset() + sd.size() - 1UL )
1746  :( sd.offset() + sd.size() ) ) )
1747  :( ( IsUpper<MT>::value )?( left.columns() - column )
1748  :( left.columns() ) ) );
1749 
1750  return submatrix<AF>( left, sd.offset(), column, sd.size(), n ) * subvector<AF>( right, column, n );
1751 }
1753 //*************************************************************************************************
1754 
1755 
1756 //*************************************************************************************************
1768 template< AlignmentFlag AF // Alignment flag
1769  , size_t... CSAs // Compile time subvector arguments
1770  , typename VT // Vector base type of the expression
1771  , typename... RSAs > // Runtime subvector arguments
1772 inline decltype(auto) subvector( const TVecMatMultExpr<VT>& vector, RSAs... args )
1773 {
1775 
1777 
1778  const SubvectorData<CSAs...> sd( args... );
1779 
1780  BLAZE_DECLTYPE_AUTO( left , (~vector).leftOperand() );
1781  BLAZE_DECLTYPE_AUTO( right, (~vector).rightOperand() );
1782 
1783  const size_t row( ( IsLower<MT>::value )
1784  ?( ( !AF && IsStrictlyLower<MT>::value )?( sd.offset() + 1UL ):( sd.offset() ) )
1785  :( 0UL ) );
1786  const size_t m( ( IsUpper<MT>::value )
1787  ?( ( IsLower<MT>::value )?( sd.size() )
1788  :( ( IsStrictlyUpper<MT>::value && sd.size() > 0UL )
1789  ?( sd.offset() + sd.size() - 1UL )
1790  :( sd.offset() + sd.size() ) ) )
1791  :( ( IsLower<MT>::value )?( right.rows() - row )
1792  :( right.rows() ) ) );
1793 
1794  return subvector<AF>( left, row, m ) * submatrix<AF>( right, row, sd.offset(), m, sd.size() );
1795 }
1797 //*************************************************************************************************
1798 
1799 
1800 
1801 
1802 //=================================================================================================
1803 //
1804 // GLOBAL RESTRUCTURING FUNCTIONS (ROW)
1805 //
1806 //=================================================================================================
1807 
1808 //*************************************************************************************************
1819 template< size_t I1 // Row index
1820  , typename MT // Type of the sparse submatrix
1821  , AlignmentFlag AF // Alignment flag
1822  , bool SO // Storage order
1823  , bool DF // Density flag
1824  , size_t I2 // Index of the first row
1825  , size_t J // Index of the first column
1826  , size_t M // Number of rows
1827  , size_t N // Number of columns
1828  , typename... RRAs > // Optional row arguments
1829 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
1830 {
1832 
1833  BLAZE_STATIC_ASSERT_MSG( I1 < M, "Invalid row access index" );
1834 
1835  return subvector<J,N>( row<I1+I2>( sm.operand(), args... ), unchecked );
1836 }
1838 //*************************************************************************************************
1839 
1840 
1841 //*************************************************************************************************
1853 template< size_t I1 // Row index
1854  , typename MT // Type of the sparse submatrix
1855  , AlignmentFlag AF // Alignment flag
1856  , bool SO // Storage order
1857  , bool DF // Density flag
1858  , size_t I2 // Index of the first row
1859  , size_t J // Index of the first column
1860  , size_t M // Number of rows
1861  , size_t N // Number of columns
1862  , typename... RRAs > // Optional row arguments
1863 inline decltype(auto) row( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
1864 {
1866 
1867  BLAZE_STATIC_ASSERT_MSG( I1 < M, "Invalid row access index" );
1868 
1869  return subvector<J,N>( row<I1+I2>( sm.operand(), args... ), unchecked );
1870 }
1872 //*************************************************************************************************
1873 
1874 
1875 //*************************************************************************************************
1887 template< size_t I1 // Row index
1888  , typename MT // Type of the sparse submatrix
1889  , AlignmentFlag AF // Alignment flag
1890  , bool SO // Storage order
1891  , bool DF // Density flag
1892  , size_t I2 // Index of the first row
1893  , size_t J // Index of the first column
1894  , size_t M // Number of rows
1895  , size_t N // Number of columns
1896  , typename... RRAs > // Optional row arguments
1897 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RRAs... args )
1898 {
1900 
1901  BLAZE_STATIC_ASSERT_MSG( I1 < M, "Invalid row access index" );
1902 
1903  return subvector<J,N>( row<I1+I2>( sm.operand(), args... ), unchecked );
1904 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1922 template< typename MT // Type of the sparse submatrix
1923  , AlignmentFlag AF // Alignment flag
1924  , bool SO // Storage order
1925  , bool DF // Density flag
1926  , size_t I // Index of the first row
1927  , size_t J // Index of the first column
1928  , size_t M // Number of rows
1929  , size_t N // Number of columns
1930  , typename... RRAs > // Optional row arguments
1931 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RRAs... args )
1932 {
1934 
1935  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
1936 
1937  if( isChecked ) {
1938  if( ( index >= M ) ) {
1939  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
1940  }
1941  }
1942  else {
1943  BLAZE_USER_ASSERT( index < M, "Invalid row access index" );
1944  }
1945 
1946  return subvector<J,N>( row( sm.operand(), I+index, args... ), unchecked );
1947 }
1949 //*************************************************************************************************
1950 
1951 
1952 //*************************************************************************************************
1966 template< typename MT // Type of the sparse submatrix
1967  , AlignmentFlag AF // Alignment flag
1968  , bool SO // Storage order
1969  , bool DF // Density flag
1970  , size_t I // Index of the first row
1971  , size_t J // Index of the first column
1972  , size_t M // Number of rows
1973  , size_t N // Number of columns
1974  , typename... RRAs > // Optional row arguments
1975 inline decltype(auto) row( const Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RRAs... args )
1976 {
1978 
1979  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
1980 
1981  if( isChecked ) {
1982  if( ( index >= M ) ) {
1983  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
1984  }
1985  }
1986  else {
1987  BLAZE_USER_ASSERT( index < M, "Invalid row access index" );
1988  }
1989 
1990  return subvector<J,N>( row( sm.operand(), I+index, args... ), unchecked );
1991 }
1993 //*************************************************************************************************
1994 
1995 
1996 //*************************************************************************************************
2010 template< typename MT // Type of the sparse submatrix
2011  , AlignmentFlag AF // Alignment flag
2012  , bool SO // Storage order
2013  , bool DF // Density flag
2014  , size_t I // Index of the first row
2015  , size_t J // Index of the first column
2016  , size_t M // Number of rows
2017  , size_t N // Number of columns
2018  , typename... RRAs > // Optional row arguments
2019 inline decltype(auto) row( Submatrix<MT,AF,SO,DF,I,J,M,N>&& sm, size_t index, RRAs... args )
2020 {
2022 
2023  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2024 
2025  if( isChecked ) {
2026  if( ( index >= M ) ) {
2027  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2028  }
2029  }
2030  else {
2031  BLAZE_USER_ASSERT( index < M, "Invalid row access index" );
2032  }
2033 
2034  return subvector<J,N>( row( sm.operand(), I+index, args... ), unchecked );
2035 }
2037 //*************************************************************************************************
2038 
2039 
2040 //*************************************************************************************************
2052 template< size_t... CRAs // Compile time row arguments
2053  , typename MT // Type of the sparse submatrix
2054  , AlignmentFlag AF // Alignment flag
2055  , bool SO // Storage order
2056  , bool DF // Density flag
2057  , typename... RRAs > // Runtime row arguments
2058 inline decltype(auto) row( Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2059 {
2061 
2062  const RowData<CRAs...> rd( args... );
2063 
2064  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2065 
2066  if( isChecked ) {
2067  if( ( rd.row() >= sm.rows() ) ) {
2068  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2069  }
2070  }
2071  else {
2072  BLAZE_USER_ASSERT( rd.row() < sm.rows(), "Invalid row access index" );
2073  }
2074 
2075  const size_t index( rd.row() + sm.row() );
2076 
2077  return subvector( row( sm.operand(), index, args... ), sm.column(), sm.columns(), unchecked );
2078 }
2080 //*************************************************************************************************
2081 
2082 
2083 //*************************************************************************************************
2096 template< size_t... CRAs // Compile time row arguments
2097  , typename MT // Type of the sparse submatrix
2098  , AlignmentFlag AF // Alignment flag
2099  , bool SO // Storage order
2100  , bool DF // Density flag
2101  , typename... RRAs > // Runtime row arguments
2102 inline decltype(auto) row( const Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2103 {
2105 
2106  const RowData<CRAs...> rd( args... );
2107 
2108  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2109 
2110  if( isChecked ) {
2111  if( ( rd.row() >= sm.rows() ) ) {
2112  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2113  }
2114  }
2115  else {
2116  BLAZE_USER_ASSERT( rd.row() < sm.rows(), "Invalid row access index" );
2117  }
2118 
2119  const size_t index( rd.row() + sm.row() );
2120 
2121  return subvector( row( sm.operand(), index, args... ), sm.column(), sm.columns(), unchecked );
2122 }
2124 //*************************************************************************************************
2125 
2126 
2127 //*************************************************************************************************
2140 template< size_t... CRAs // Compile time row arguments
2141  , typename MT // Type of the sparse submatrix
2142  , AlignmentFlag AF // Alignment flag
2143  , bool SO // Storage order
2144  , bool DF // Density flag
2145  , typename... RRAs > // Runtime row arguments
2146 inline decltype(auto) row( Submatrix<MT,AF,SO,DF>&& sm, RRAs... args )
2147 {
2149 
2150  const RowData<CRAs...> rd( args... );
2151 
2152  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2153 
2154  if( isChecked ) {
2155  if( ( rd.row() >= sm.rows() ) ) {
2156  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2157  }
2158  }
2159  else {
2160  BLAZE_USER_ASSERT( rd.row() < sm.rows(), "Invalid row access index" );
2161  }
2162 
2163  const size_t index( rd.row() + sm.row() );
2164 
2165  return subvector( row( sm.operand(), index, args... ), sm.column(), sm.columns(), unchecked );
2166 }
2168 //*************************************************************************************************
2169 
2170 
2171 
2172 
2173 //=================================================================================================
2174 //
2175 // GLOBAL RESTRUCTURING FUNCTIONS (ROWS)
2176 //
2177 //=================================================================================================
2178 
2179 //*************************************************************************************************
2190 template< size_t I1 // First row index
2191  , size_t... Is // Remaining row indices
2192  , typename MT // Type of the sparse submatrix
2193  , AlignmentFlag AF // Alignment flag
2194  , bool SO // Storage order
2195  , bool DF // Density flag
2196  , size_t I2 // Index of the first row
2197  , size_t J // Index of the first column
2198  , size_t M // Number of rows
2199  , size_t N // Number of columns
2200  , typename... RRAs > // Optional row arguments
2201 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
2202 {
2204 
2205  return submatrix<0UL,J,sizeof...(Is)+1UL,N>(
2206  rows( sm.operand(), make_shifted_index_subsequence<I2,M,I1,Is...>(), args... ), unchecked );
2207 }
2209 //*************************************************************************************************
2210 
2211 
2212 //*************************************************************************************************
2224 template< size_t I1 // First row index
2225  , size_t... Is // Remaining row indices
2226  , typename MT // Type of the sparse submatrix
2227  , AlignmentFlag AF // Alignment flag
2228  , bool SO // Storage order
2229  , bool DF // Density flag
2230  , size_t I2 // Index of the first row
2231  , size_t J // Index of the first column
2232  , size_t M // Number of rows
2233  , size_t N // Number of columns
2234  , typename... RRAs > // Optional row arguments
2235 inline decltype(auto) rows( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RRAs... args )
2236 {
2238 
2239  return submatrix<0UL,J,sizeof...(Is)+1UL,N>(
2240  rows( sm.operand(), make_shifted_index_subsequence<I2,M,I1,Is...>(), args... ), unchecked );
2241 }
2243 //*************************************************************************************************
2244 
2245 
2246 //*************************************************************************************************
2258 template< size_t I1 // First row index
2259  , size_t... Is // Remaining row indices
2260  , typename MT // Type of the sparse submatrix
2261  , AlignmentFlag AF // Alignment flag
2262  , bool SO // Storage order
2263  , bool DF // Density flag
2264  , size_t I2 // Index of the first row
2265  , size_t J // Index of the first column
2266  , size_t M // Number of rows
2267  , size_t N // Number of columns
2268  , typename... RRAs > // Optional row arguments
2269 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RRAs... args )
2270 {
2272 
2273  return submatrix<0UL,J,sizeof...(Is)+1UL,N>(
2274  rows( sm.operand(), make_shifted_index_subsequence<I2,M,I1,Is...>(), args... ), unchecked );
2275 }
2277 //*************************************************************************************************
2278 
2279 
2280 //*************************************************************************************************
2292 template< size_t I1 // First row index
2293  , size_t... Is // Remaining row indices
2294  , typename MT // Type of the sparse submatrix
2295  , AlignmentFlag AF // Alignment flag
2296  , bool SO // Storage order
2297  , bool DF // Density flag
2298  , typename... RRAs > // Optional row arguments
2299 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2300 {
2302 
2303  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2304 
2305  if( isChecked ) {
2306  static constexpr size_t indices[] = { I1, Is... };
2307  for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
2308  if( sm.rows() <= indices[i] ) {
2309  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2310  }
2311  }
2312  }
2313 
2314  return submatrix( rows( sm.operand(), { I1+sm.row(), Is+sm.row()... }, args... ),
2315  0UL, sm.column(), sizeof...(Is)+1UL, sm.columns(), unchecked );
2316 }
2318 //*************************************************************************************************
2319 
2320 
2321 //*************************************************************************************************
2334 template< size_t I1 // First row index
2335  , size_t... Is // Remaining row indices
2336  , typename MT // Type of the sparse submatrix
2337  , AlignmentFlag AF // Alignment flag
2338  , bool SO // Storage order
2339  , bool DF // Density flag
2340  , typename... RRAs > // Optional row arguments
2341 inline decltype(auto) rows( const Submatrix<MT,AF,SO,DF>& sm, RRAs... args )
2342 {
2344 
2345  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2346 
2347  if( isChecked ) {
2348  static constexpr size_t indices[] = { I1, Is... };
2349  for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
2350  if( sm.rows() <= indices[i] ) {
2351  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2352  }
2353  }
2354  }
2355 
2356  return submatrix( rows( sm.operand(), { I1+sm.row(), Is+sm.row()... }, args... ),
2357  0UL, sm.column(), sizeof...(Is)+1UL, sm.columns(), unchecked );
2358 }
2360 //*************************************************************************************************
2361 
2362 
2363 //*************************************************************************************************
2376 template< size_t I1 // First row index
2377  , size_t... Is // Remaining row indices
2378  , typename MT // Type of the sparse submatrix
2379  , AlignmentFlag AF // Alignment flag
2380  , bool SO // Storage order
2381  , bool DF // Density flag
2382  , typename... RRAs > // Optional row arguments
2383 inline decltype(auto) rows( Submatrix<MT,AF,SO,DF>&& sm, RRAs... args )
2384 {
2386 
2387  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2388 
2389  if( isChecked ) {
2390  static constexpr size_t indices[] = { I1, Is... };
2391  for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
2392  if( sm.rows() <= indices[i] ) {
2393  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2394  }
2395  }
2396  }
2397 
2398  return submatrix( rows( sm.operand(), { I1+sm.row(), Is+sm.row()... }, args... ),
2399  0UL, sm.column(), sizeof...(Is)+1UL, sm.columns(), unchecked );
2400 }
2402 //*************************************************************************************************
2403 
2404 
2405 //*************************************************************************************************
2419 template< typename MT // Type of the sparse submatrix
2420  , AlignmentFlag AF // Alignment flag
2421  , bool SO // Storage order
2422  , bool DF // Density flag
2423  , size_t... CSAs // Compile time submatrix arguments
2424  , typename T // Type of the row indices
2425  , typename... RRAs > // Optional row arguments
2426 inline decltype(auto)
2427  rows( Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RRAs... args )
2428 {
2430 
2431  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2432 
2433  if( isChecked ) {
2434  for( size_t i=0UL; i<n; ++i ) {
2435  if( sm.rows() <= indices[i] ) {
2436  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row specification" );
2437  }
2438  }
2439  }
2440 
2441  SmallVector<size_t,128UL> newIndices( indices, indices+n );
2442  std::for_each( newIndices.begin(), newIndices.end(),
2443  [row=sm.row()]( size_t& index ){ index += row; } );
2444 
2445  return submatrix( rows( sm.operand(), newIndices.data(), n, args... ),
2446  0UL, sm.column(), n, sm.columns(), unchecked );
2447 }
2449 //*************************************************************************************************
2450 
2451 
2452 //*************************************************************************************************
2467 template< typename MT // Type of the sparse submatrix
2468  , AlignmentFlag AF // Alignment flag
2469  , bool SO // Storage order
2470  , bool DF // Density flag
2471  , size_t... CSAs // Compile time submatrix arguments
2472  , typename T // Type of the row indices
2473  , typename... RRAs > // Optional row arguments
2474 inline decltype(auto)
2475  rows( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RRAs... args )
2476 {
2478 
2479  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2480 
2481  if( isChecked ) {
2482  for( size_t i=0UL; i<n; ++i ) {
2483  if( sm.rows() <= indices[i] ) {
2484  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row specification" );
2485  }
2486  }
2487  }
2488 
2489  SmallVector<size_t,128UL> newIndices( indices, indices+n );
2490  std::for_each( newIndices.begin(), newIndices.end(),
2491  [row=sm.row()]( size_t& index ){ index += row; } );
2492 
2493  return submatrix( rows( sm.operand(), newIndices.data(), n, args... ),
2494  0UL, sm.column(), n, sm.columns(), unchecked );
2495 }
2497 //*************************************************************************************************
2498 
2499 
2500 //*************************************************************************************************
2515 template< typename MT // Type of the sparse submatrix
2516  , AlignmentFlag AF // Alignment flag
2517  , bool SO // Storage order
2518  , bool DF // Density flag
2519  , size_t... CSAs // Compile time submatrix arguments
2520  , typename T // Type of the row indices
2521  , typename... RRAs > // Optional row arguments
2522 inline decltype(auto)
2523  rows( Submatrix<MT,AF,SO,DF,CSAs...>&& sm, const T* indices, size_t n, RRAs... args )
2524 {
2526 
2527  constexpr bool isChecked( !Contains< TypeList<RRAs...>, Unchecked >::value );
2528 
2529  if( isChecked ) {
2530  for( size_t i=0UL; i<n; ++i ) {
2531  if( sm.rows() <= indices[i] ) {
2532  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row specification" );
2533  }
2534  }
2535  }
2536 
2537  SmallVector<size_t,128UL> newIndices( indices, indices+n );
2538  std::for_each( newIndices.begin(), newIndices.end(),
2539  [row=sm.row()]( size_t& index ){ index += row; } );
2540 
2541  return submatrix( rows( sm.operand(), newIndices.data(), n, args... ),
2542  0UL, sm.column(), n, sm.columns(), unchecked );
2543 }
2545 //*************************************************************************************************
2546 
2547 
2548 
2549 
2550 //=================================================================================================
2551 //
2552 // GLOBAL RESTRUCTURING FUNCTIONS (COLUMN)
2553 //
2554 //=================================================================================================
2555 
2556 //*************************************************************************************************
2567 template< size_t I1 // Column index
2568  , typename MT // Type of the sparse submatrix
2569  , AlignmentFlag AF // Alignment flag
2570  , bool SO // Storage order
2571  , bool DF // Density flag
2572  , size_t I2 // Index of the first row
2573  , size_t J // Index of the first column
2574  , size_t M // Number of rows
2575  , size_t N // Number of columns
2576  , typename... RCAs > // Optional column arguments
2577 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
2578 {
2580 
2581  BLAZE_STATIC_ASSERT_MSG( I1 < N, "Invalid column access index" );
2582 
2583  return subvector<I2,M>( column<I1+J>( sm.operand(), args... ), unchecked );
2584 }
2586 //*************************************************************************************************
2587 
2588 
2589 //*************************************************************************************************
2601 template< size_t I1 // Column index
2602  , typename MT // Type of the sparse submatrix
2603  , AlignmentFlag AF // Alignment flag
2604  , bool SO // Storage order
2605  , bool DF // Density flag
2606  , size_t I2 // Index of the first row
2607  , size_t J // Index of the first column
2608  , size_t M // Number of rows
2609  , size_t N // Number of columns
2610  , typename... RCAs > // Optional column arguments
2611 inline decltype(auto) column( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
2612 {
2614 
2615  BLAZE_STATIC_ASSERT_MSG( I1 < N, "Invalid column access index" );
2616 
2617  return subvector<I2,M>( column<I1+J>( sm.operand(), args... ), unchecked );
2618 }
2620 //*************************************************************************************************
2621 
2622 
2623 //*************************************************************************************************
2635 template< size_t I1 // Column index
2636  , typename MT // Type of the sparse submatrix
2637  , AlignmentFlag AF // Alignment flag
2638  , bool SO // Storage order
2639  , bool DF // Density flag
2640  , size_t I2 // Index of the first row
2641  , size_t J // Index of the first column
2642  , size_t M // Number of rows
2643  , size_t N // Number of columns
2644  , typename... RCAs > // Optional column arguments
2645 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RCAs... args )
2646 {
2648 
2649  BLAZE_STATIC_ASSERT_MSG( I1 < N, "Invalid column access index" );
2650 
2651  return subvector<I2,M>( column<I1+J>( sm.operand(), args... ), unchecked );
2652 }
2654 //*************************************************************************************************
2655 
2656 
2657 //*************************************************************************************************
2670 template< typename MT // Type of the sparse submatrix
2671  , AlignmentFlag AF // Alignment flag
2672  , bool SO // Storage order
2673  , bool DF // Density flag
2674  , size_t I // Index of the first row
2675  , size_t J // Index of the first column
2676  , size_t M // Number of rows
2677  , size_t N // Number of columns
2678  , typename... RCAs > // Optional column arguments
2679 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RCAs... args )
2680 {
2682 
2683  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
2684 
2685  if( isChecked ) {
2686  if( ( index >= N ) ) {
2687  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2688  }
2689  }
2690  else {
2691  BLAZE_USER_ASSERT( index < N, "Invalid column access index" );
2692  }
2693 
2694  return subvector<I,M>( column( sm.operand(), J+index, args... ), unchecked );
2695 }
2697 //*************************************************************************************************
2698 
2699 
2700 //*************************************************************************************************
2714 template< typename MT // Type of the sparse submatrix
2715  , AlignmentFlag AF // Alignment flag
2716  , bool SO // Storage order
2717  , bool DF // Density flag
2718  , size_t I // Index of the first row
2719  , size_t J // Index of the first column
2720  , size_t M // Number of rows
2721  , size_t N // Number of columns
2722  , typename... RCAs > // Optional column arguments
2723 inline decltype(auto) column( const Submatrix<MT,AF,SO,DF,I,J,M,N>& sm, size_t index, RCAs... args )
2724 {
2726 
2727  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
2728 
2729  if( isChecked ) {
2730  if( ( index >= N ) ) {
2731  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2732  }
2733  }
2734  else {
2735  BLAZE_USER_ASSERT( index < N, "Invalid column access index" );
2736  }
2737 
2738  return subvector<I,M>( column( sm.operand(), J+index, args... ), unchecked );
2739 }
2741 //*************************************************************************************************
2742 
2743 
2744 //*************************************************************************************************
2758 template< typename MT // Type of the sparse submatrix
2759  , AlignmentFlag AF // Alignment flag
2760  , bool SO // Storage order
2761  , bool DF // Density flag
2762  , size_t I // Index of the first row
2763  , size_t J // Index of the first column
2764  , size_t M // Number of rows
2765  , size_t N // Number of columns
2766  , typename... RCAs > // Optional column arguments
2767 inline decltype(auto) column( Submatrix<MT,AF,SO,DF,I,J,M,N>&& sm, size_t index, RCAs... args )
2768 {
2770 
2771  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
2772 
2773  if( isChecked ) {
2774  if( ( index >= N ) ) {
2775  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2776  }
2777  }
2778  else {
2779  BLAZE_USER_ASSERT( index < N, "Invalid column access index" );
2780  }
2781 
2782  return subvector<I,M>( column( sm.operand(), J+index, args... ), unchecked );
2783 }
2785 //*************************************************************************************************
2786 
2787 
2788 //*************************************************************************************************
2800 template< size_t... CCAs // Compile time column arguments
2801  , typename MT // Type of the sparse submatrix
2802  , AlignmentFlag AF // Alignment flag
2803  , bool SO // Storage order
2804  , bool DF // Density flag
2805  , typename... RCAs > // Runtime column arguments
2806 inline decltype(auto) column( Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
2807 {
2809 
2810  const ColumnData<CCAs...> cd( args... );
2811 
2812  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
2813 
2814  if( isChecked ) {
2815  if( ( cd.column() >= sm.columns() ) ) {
2816  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2817  }
2818  }
2819  else {
2820  BLAZE_USER_ASSERT( cd.column() < sm.columns(), "Invalid column access index" );
2821  }
2822 
2823  const size_t index( cd.column() + sm.column() );
2824 
2825  return subvector( column( sm.operand(), index, args... ), sm.row(), sm.rows(), unchecked );
2826 }
2828 //*************************************************************************************************
2829 
2830 
2831 //*************************************************************************************************
2844 template< size_t... CCAs // Compile time column arguments
2845  , typename MT // Type of the sparse submatrix
2846  , AlignmentFlag AF // Alignment flag
2847  , bool SO // Storage order
2848  , bool DF // Density flag
2849  , typename... RCAs > // Runtime column arguments
2850 inline decltype(auto) column( const Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
2851 {
2853 
2854  const ColumnData<CCAs...> cd( args... );
2855 
2856  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
2857 
2858  if( isChecked ) {
2859  if( ( cd.column() >= sm.columns() ) ) {
2860  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2861  }
2862  }
2863  else {
2864  BLAZE_USER_ASSERT( cd.column() < sm.columns(), "Invalid column access index" );
2865  }
2866 
2867  const size_t index( cd.column() + sm.column() );
2868 
2869  return subvector( column( sm.operand(), index, args... ), sm.row(), sm.rows(), unchecked );
2870 }
2872 //*************************************************************************************************
2873 
2874 
2875 //*************************************************************************************************
2888 template< size_t... CCAs // Compile time column arguments
2889  , typename MT // Type of the sparse submatrix
2890  , AlignmentFlag AF // Alignment flag
2891  , bool SO // Storage order
2892  , bool DF // Density flag
2893  , typename... RCAs > // Runtime column arguments
2894 inline decltype(auto) column( Submatrix<MT,AF,SO,DF>&& sm, RCAs... args )
2895 {
2897 
2898  const ColumnData<CCAs...> cd( args... );
2899 
2900  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
2901 
2902  if( isChecked ) {
2903  if( ( cd.column() >= sm.columns() ) ) {
2904  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2905  }
2906  }
2907  else {
2908  BLAZE_USER_ASSERT( cd.column() < sm.columns(), "Invalid column access index" );
2909  }
2910 
2911  const size_t index( cd.column() + sm.column() );
2912 
2913  return subvector( column( sm.operand(), index, args... ), sm.row(), sm.rows(), unchecked );
2914 }
2916 //*************************************************************************************************
2917 
2918 
2919 
2920 
2921 //=================================================================================================
2922 //
2923 // GLOBAL RESTRUCTURING FUNCTIONS (COLUMNS)
2924 //
2925 //=================================================================================================
2926 
2927 //*************************************************************************************************
2938 template< size_t I1 // First column index
2939  , size_t... Is // Remaining column indices
2940  , typename MT // Type of the sparse submatrix
2941  , AlignmentFlag AF // Alignment flag
2942  , bool SO // Storage order
2943  , bool DF // Density flag
2944  , size_t I2 // Index of the first row
2945  , size_t J // Index of the first column
2946  , size_t M // Number of rows
2947  , size_t N // Number of columns
2948  , typename... RCAs > // Optional column arguments
2949 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
2950 {
2952 
2953  return submatrix<I2,0UL,M,sizeof...(Is)+1UL>(
2954  columns( sm.operand(), make_shifted_index_subsequence<J,N,I1,Is...>(), args... ), unchecked );
2955 }
2957 //*************************************************************************************************
2958 
2959 
2960 //*************************************************************************************************
2972 template< size_t I1 // First column index
2973  , size_t... Is // Remaining column indices
2974  , typename MT // Type of the sparse submatrix
2975  , AlignmentFlag AF // Alignment flag
2976  , bool SO // Storage order
2977  , bool DF // Density flag
2978  , size_t I2 // Index of the first row
2979  , size_t J // Index of the first column
2980  , size_t M // Number of rows
2981  , size_t N // Number of columns
2982  , typename... RCAs > // Optional column arguments
2983 inline decltype(auto) columns( const Submatrix<MT,AF,SO,DF,I2,J,M,N>& sm, RCAs... args )
2984 {
2986 
2987  return submatrix<I2,0UL,M,sizeof...(Is)+1UL>(
2988  columns( sm.operand(), make_shifted_index_subsequence<J,N,I1,Is...>(), args... ), unchecked );
2989 }
2991 //*************************************************************************************************
2992 
2993 
2994 //*************************************************************************************************
3006 template< size_t I1 // First column index
3007  , size_t... Is // Remaining column indices
3008  , typename MT // Type of the sparse submatrix
3009  , AlignmentFlag AF // Alignment flag
3010  , bool SO // Storage order
3011  , bool DF // Density flag
3012  , size_t I2 // Index of the first row
3013  , size_t J // Index of the first column
3014  , size_t M // Number of rows
3015  , size_t N // Number of columns
3016  , typename... RCAs > // Optional column arguments
3017 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF,I2,J,M,N>&& sm, RCAs... args )
3018 {
3020 
3021  return submatrix<I2,0UL,M,sizeof...(Is)+1UL>(
3022  columns( sm.operand(), make_shifted_index_subsequence<J,N,I1,Is...>(), args... ), unchecked );
3023 }
3025 //*************************************************************************************************
3026 
3027 
3028 //*************************************************************************************************
3040 template< size_t I1 // First column index
3041  , size_t... Is // Remaining column indices
3042  , typename MT // Type of the sparse submatrix
3043  , AlignmentFlag AF // Alignment flag
3044  , bool SO // Storage order
3045  , bool DF // Density flag
3046  , typename... RCAs > // Optional column arguments
3047 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
3048 {
3050 
3051  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
3052 
3053  if( isChecked ) {
3054  static constexpr size_t indices[] = { I1, Is... };
3055  for( size_t j=0UL; j<sizeof...(Is)+1UL; ++j ) {
3056  if( sm.columns() <= indices[j] ) {
3057  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3058  }
3059  }
3060  }
3061 
3062  return submatrix( columns( sm.operand(), { I1+sm.column(), Is+sm.column()... }, args... ),
3063  sm.row(), 0UL, sm.rows(), sizeof...(Is)+1UL, unchecked );
3064 }
3066 //*************************************************************************************************
3067 
3068 
3069 //*************************************************************************************************
3082 template< size_t I1 // First column index
3083  , size_t... Is // Remaining column indices
3084  , typename MT // Type of the sparse submatrix
3085  , AlignmentFlag AF // Alignment flag
3086  , bool SO // Storage order
3087  , bool DF // Density flag
3088  , typename... RCAs > // Optional column arguments
3089 inline decltype(auto) columns( const Submatrix<MT,AF,SO,DF>& sm, RCAs... args )
3090 {
3092 
3093  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
3094 
3095  if( isChecked ) {
3096  static constexpr size_t indices[] = { I1, Is... };
3097  for( size_t j=0UL; j<sizeof...(Is)+1UL; ++j ) {
3098  if( sm.columns() <= indices[j] ) {
3099  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3100  }
3101  }
3102  }
3103 
3104  return submatrix( columns( sm.operand(), { I1+sm.column(), Is+sm.column()... }, args... ),
3105  sm.row(), 0UL, sm.rows(), sizeof...(Is)+1UL, unchecked );
3106 }
3108 //*************************************************************************************************
3109 
3110 
3111 //*************************************************************************************************
3124 template< size_t I1 // First column index
3125  , size_t... Is // Remaining column indices
3126  , typename MT // Type of the sparse submatrix
3127  , AlignmentFlag AF // Alignment flag
3128  , bool SO // Storage order
3129  , bool DF // Density flag
3130  , typename... RCAs > // Optional column arguments
3131 inline decltype(auto) columns( Submatrix<MT,AF,SO,DF>&& sm, RCAs... args )
3132 {
3134 
3135  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
3136 
3137  if( isChecked ) {
3138  static constexpr size_t indices[] = { I1, Is... };
3139  for( size_t j=0UL; j<sizeof...(Is)+1UL; ++j ) {
3140  if( sm.columns() <= indices[j] ) {
3141  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3142  }
3143  }
3144  }
3145 
3146  return submatrix( columns( sm.operand(), { I1+sm.column(), Is+sm.column()... }, args... ),
3147  sm.row(), 0UL, sm.rows(), sizeof...(Is)+1UL, unchecked );
3148 }
3150 //*************************************************************************************************
3151 
3152 
3153 //*************************************************************************************************
3167 template< typename MT // Type of the sparse submatrix
3168  , AlignmentFlag AF // Alignment flag
3169  , bool SO // Storage order
3170  , bool DF // Density flag
3171  , size_t... CSAs // Compile time submatrix arguments
3172  , typename T // Type of the column indices
3173  , typename... RCAs > // Optional column arguments
3174 inline decltype(auto)
3175  columns( Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RCAs... args )
3176 {
3178 
3179  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
3180 
3181  if( isChecked ) {
3182  for( size_t j=0UL; j<n; ++j ) {
3183  if( sm.columns() <= indices[j] ) {
3184  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column specification" );
3185  }
3186  }
3187  }
3188 
3189  SmallVector<size_t,128UL> newIndices( indices, indices+n );
3190  std::for_each( newIndices.begin(), newIndices.end(),
3191  [column=sm.column()]( size_t& index ){ index += column; } );
3192 
3193  return submatrix( columns( sm.operand(), newIndices.data(), n, args... ),
3194  sm.row(), 0UL, sm.rows(), n, unchecked );
3195 }
3197 //*************************************************************************************************
3198 
3199 
3200 //*************************************************************************************************
3215 template< typename MT // Type of the sparse submatrix
3216  , AlignmentFlag AF // Alignment flag
3217  , bool SO // Storage order
3218  , bool DF // Density flag
3219  , size_t... CSAs // Compile time submatrix arguments
3220  , typename T // Type of the column indices
3221  , typename... RCAs > // Optional column arguments
3222 inline decltype(auto)
3223  columns( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, const T* indices, size_t n, RCAs... args )
3224 {
3226 
3227  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
3228 
3229  if( isChecked ) {
3230  for( size_t j=0UL; j<n; ++j ) {
3231  if( sm.columns() <= indices[j] ) {
3232  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column specification" );
3233  }
3234  }
3235  }
3236 
3237  SmallVector<size_t,128UL> newIndices( indices, indices+n );
3238  std::for_each( newIndices.begin(), newIndices.end(),
3239  [column=sm.column()]( size_t& index ){ index += column; } );
3240 
3241  return submatrix( columns( sm.operand(), newIndices.data(), n, args... ),
3242  sm.row(), 0UL, sm.rows(), n, unchecked );
3243 }
3245 //*************************************************************************************************
3246 
3247 
3248 //*************************************************************************************************
3263 template< typename MT // Type of the sparse submatrix
3264  , AlignmentFlag AF // Alignment flag
3265  , bool SO // Storage order
3266  , bool DF // Density flag
3267  , size_t... CSAs // Compile time submatrix arguments
3268  , typename T // Type of the column indices
3269  , typename... RCAs > // Optional column arguments
3270 inline decltype(auto)
3271  columns( Submatrix<MT,AF,SO,DF,CSAs...>&& sm, const T* indices, size_t n, RCAs... args )
3272 {
3274 
3275  constexpr bool isChecked( !Contains< TypeList<RCAs...>, Unchecked >::value );
3276 
3277  if( isChecked ) {
3278  for( size_t j=0UL; j<n; ++j ) {
3279  if( sm.columns() <= indices[j] ) {
3280  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column specification" );
3281  }
3282  }
3283  }
3284 
3285  SmallVector<size_t,128UL> newIndices( indices, indices+n );
3286  std::for_each( newIndices.begin(), newIndices.end(),
3287  [column=sm.column()]( size_t& index ){ index += column; } );
3288 
3289  return submatrix( columns( sm.operand(), newIndices.data(), n, args... ),
3290  sm.row(), 0UL, sm.rows(), n, unchecked );
3291 }
3293 //*************************************************************************************************
3294 
3295 
3296 
3297 
3298 //=================================================================================================
3299 //
3300 // SUBMATRIX OPERATORS
3301 //
3302 //=================================================================================================
3303 
3304 //*************************************************************************************************
3312 template< typename MT // Type of the matrix
3313  , AlignmentFlag AF // Alignment flag
3314  , bool SO // Storage order
3315  , bool DF // Density flag
3316  , size_t... CSAs > // Compile time submatrix arguments
3317 inline void reset( Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3318 {
3319  sm.reset();
3320 }
3322 //*************************************************************************************************
3323 
3324 
3325 //*************************************************************************************************
3333 template< typename MT // Type of the matrix
3334  , AlignmentFlag AF // Alignment flag
3335  , bool SO // Storage order
3336  , bool DF // Density flag
3337  , size_t... CSAs > // Compile time submatrix arguments
3338 inline void reset( Submatrix<MT,AF,SO,DF,CSAs...>&& sm )
3339 {
3340  sm.reset();
3341 }
3343 //*************************************************************************************************
3344 
3345 
3346 //*************************************************************************************************
3360 template< typename MT // Type of the matrix
3361  , AlignmentFlag AF // Alignment flag
3362  , bool SO // Storage order
3363  , bool DF // Density flag
3364  , size_t... CSAs > // Compile time submatrix arguments
3365 inline void reset( Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i )
3366 {
3367  sm.reset( i );
3368 }
3370 //*************************************************************************************************
3371 
3372 
3373 //*************************************************************************************************
3383 template< typename MT // Type of the matrix
3384  , AlignmentFlag AF // Alignment flag
3385  , bool SO // Storage order
3386  , bool DF // Density flag
3387  , size_t... CSAs > // Compile time submatrix arguments
3388 inline void clear( Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3389 {
3390  sm.reset();
3391 }
3393 //*************************************************************************************************
3394 
3395 
3396 //*************************************************************************************************
3406 template< typename MT // Type of the matrix
3407  , AlignmentFlag AF // Alignment flag
3408  , bool SO // Storage order
3409  , bool DF // Density flag
3410  , size_t... CSAs > // Compile time submatrix arguments
3411 inline void clear( Submatrix<MT,AF,SO,DF,CSAs...>&& sm )
3412 {
3413  sm.reset();
3414 }
3416 //*************************************************************************************************
3417 
3418 
3419 //*************************************************************************************************
3445 template< bool RF // Relaxation flag
3446  , typename MT // Type of the dense matrix
3447  , AlignmentFlag AF // Alignment flag
3448  , bool SO // Storage order
3449  , size_t... CSAs > // Compile time submatrix arguments
3450 inline bool isDefault( const Submatrix<MT,AF,SO,true,CSAs...>& sm )
3451 {
3452  using blaze::isDefault;
3453 
3454  if( SO == rowMajor ) {
3455  for( size_t i=0UL; i<(~sm).rows(); ++i )
3456  for( size_t j=0UL; j<(~sm).columns(); ++j )
3457  if( !isDefault<RF>( (~sm)(i,j) ) )
3458  return false;
3459  }
3460  else {
3461  for( size_t j=0UL; j<(~sm).columns(); ++j )
3462  for( size_t i=0UL; i<(~sm).rows(); ++i )
3463  if( !isDefault<RF>( (~sm)(i,j) ) )
3464  return false;
3465  }
3466 
3467  return true;
3468 }
3470 //*************************************************************************************************
3471 
3472 
3473 //*************************************************************************************************
3499 template< bool RF // Relaxation flag
3500  , typename MT // Type of the sparse matrix
3501  , AlignmentFlag AF // Alignment flag
3502  , bool SO // Storage order
3503  , size_t... CSAs > // Compile time submatrix arguments
3504 inline bool isDefault( const Submatrix<MT,AF,SO,false,CSAs...>& sm )
3505 {
3506  using blaze::isDefault;
3507 
3508  const size_t iend( ( SO == rowMajor)?( sm.rows() ):( sm.columns() ) );
3509 
3510  for( size_t i=0UL; i<iend; ++i ) {
3511  for( auto element=sm.cbegin(i); element!=sm.cend(i); ++element )
3512  if( !isDefault<RF>( element->value() ) ) return false;
3513  }
3514 
3515  return true;
3516 }
3518 //*************************************************************************************************
3519 
3520 
3521 //*************************************************************************************************
3540 template< typename MT // Type of the matrix
3541  , AlignmentFlag AF // Alignment flag
3542  , bool SO // Storage order
3543  , bool DF // Density flag
3544  , size_t... CSAs > // Compile time submatrix arguments
3545 inline bool isIntact( const Submatrix<MT,AF,SO,DF,CSAs...>& sm ) noexcept
3546 {
3547  return ( sm.row() + sm.rows() <= sm.operand().rows() &&
3548  sm.column() + sm.columns() <= sm.operand().columns() &&
3549  isIntact( sm.operand() ) );
3550 }
3552 //*************************************************************************************************
3553 
3554 
3555 //*************************************************************************************************
3576 template< typename MT // Type of the matrix
3577  , AlignmentFlag AF // Alignment flag
3578  , bool SO // Storage order
3579  , bool DF // Density flag
3580  , size_t... CSAs > // Compile time submatrix arguments
3581 inline bool isSymmetric( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3582 {
3583  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3584 
3585  if( IsSymmetric<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3586  return true;
3587  else return isSymmetric( static_cast<const BaseType&>( sm ) );
3588 }
3590 //*************************************************************************************************
3591 
3592 
3593 //*************************************************************************************************
3614 template< typename MT // Type of the matrix
3615  , AlignmentFlag AF // Alignment flag
3616  , bool SO // Storage order
3617  , bool DF // Density flag
3618  , size_t... CSAs > // Compile time submatrix arguments
3619 inline bool isHermitian( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3620 {
3621  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3622 
3623  if( IsHermitian<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3624  return true;
3625  else return isHermitian( static_cast<const BaseType&>( sm ) );
3626 }
3628 //*************************************************************************************************
3629 
3630 
3631 //*************************************************************************************************
3662 template< typename MT // Type of the matrix
3663  , AlignmentFlag AF // Alignment flag
3664  , bool SO // Storage order
3665  , bool DF // Density flag
3666  , size_t... CSAs > // Compile time submatrix arguments
3667 inline bool isLower( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3668 {
3669  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3670 
3671  if( IsLower<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3672  return true;
3673  else return isLower( static_cast<const BaseType&>( sm ) );
3674 }
3676 //*************************************************************************************************
3677 
3678 
3679 //*************************************************************************************************
3709 template< typename MT // Type of the matrix
3710  , AlignmentFlag AF // Alignment flag
3711  , bool SO // Storage order
3712  , bool DF // Density flag
3713  , size_t... CSAs > // Compile time submatrix arguments
3714 inline bool isUniLower( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3715 {
3716  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3717 
3718  if( IsUniLower<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3719  return true;
3720  else return isUniLower( static_cast<const BaseType&>( sm ) );
3721 }
3723 //*************************************************************************************************
3724 
3725 
3726 //*************************************************************************************************
3756 template< typename MT // Type of the matrix
3757  , AlignmentFlag AF // Alignment flag
3758  , bool SO // Storage order
3759  , bool DF // Density flag
3760  , size_t... CSAs > // Compile time submatrix arguments
3761 inline bool isStrictlyLower( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3762 {
3763  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3764 
3765  if( IsStrictlyLower<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3766  return true;
3767  else return isStrictlyLower( static_cast<const BaseType&>( sm ) );
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3804 template< typename MT // Type of the matrix
3805  , AlignmentFlag AF // Alignment flag
3806  , bool SO // Storage order
3807  , bool DF // Density flag
3808  , size_t... CSAs > // Compile time submatrix arguments
3809 inline bool isUpper( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3810 {
3811  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3812 
3813  if( IsUpper<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3814  return true;
3815  else return isUpper( static_cast<const BaseType&>( sm ) );
3816 }
3818 //*************************************************************************************************
3819 
3820 
3821 //*************************************************************************************************
3851 template< typename MT // Type of the matrix
3852  , AlignmentFlag AF // Alignment flag
3853  , bool SO // Storage order
3854  , bool DF // Density flag
3855  , size_t... CSAs > // Compile time submatrix arguments
3856 inline bool isUniUpper( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3857 {
3858  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3859 
3860  if( IsUniUpper<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3861  return true;
3862  else return isUniUpper( static_cast<const BaseType&>( sm ) );
3863 }
3865 //*************************************************************************************************
3866 
3867 
3868 //*************************************************************************************************
3898 template< typename MT // Type of the matrix
3899  , AlignmentFlag AF // Alignment flag
3900  , bool SO // Storage order
3901  , bool DF // Density flag
3902  , size_t... CSAs > // Compile time submatrix arguments
3903 inline bool isStrictlyUpper( const Submatrix<MT,AF,SO,DF,CSAs...>& sm )
3904 {
3905  using BaseType = BaseType_< Submatrix<MT,AF,SO,DF,CSAs...> >;
3906 
3907  if( IsStrictlyUpper<MT>::value && sm.row() == sm.column() && sm.rows() == sm.columns() )
3908  return true;
3909  else return isStrictlyUpper( static_cast<const BaseType&>( sm ) );
3910 }
3912 //*************************************************************************************************
3913 
3914 
3915 //*************************************************************************************************
3928 template< typename MT // Type of the matrix
3929  , AlignmentFlag AF // Alignment flag
3930  , bool SO // Storage order
3931  , bool DF // Density flag
3932  , size_t... CSAs > // Compile time submatrix arguments
3933 inline bool isSame( const Submatrix<MT,AF,SO,DF,CSAs...>& a, const Matrix<MT,SO>& b ) noexcept
3934 {
3935  return ( isSame( a.operand(), ~b ) &&
3936  ( a.rows() == (~b).rows() ) &&
3937  ( a.columns() == (~b).columns() ) );
3938 }
3940 //*************************************************************************************************
3941 
3942 
3943 //*************************************************************************************************
3956 template< typename MT // Type of the matrix
3957  , bool SO // Storage order
3958  , AlignmentFlag AF // Alignment flag
3959  , bool DF // Density flag
3960  , size_t... CSAs > // Compile time submatrix arguments
3961 inline bool isSame( const Matrix<MT,SO>& a, const Submatrix<MT,AF,SO,DF,CSAs...>& b ) noexcept
3962 {
3963  return ( isSame( ~a, b.operand() ) &&
3964  ( (~a).rows() == b.rows() ) &&
3965  ( (~a).columns() == b.columns() ) );
3966 }
3968 //*************************************************************************************************
3969 
3970 
3971 //*************************************************************************************************
3984 template< typename MT1 // Type of the matrix of the left-hand side submatrix
3985  , AlignmentFlag AF1 // Alignment flag of the left-hand side submatrix
3986  , bool SO1 // Storage order of the left-hand side submatrix
3987  , bool DF1 // Density flag of the left-hand side submatrix
3988  , size_t... CSAs1 // Compile time submatrix arguments of the left-hand side submatrix
3989  , typename MT2 // Type of the matrix of the right-hand side submatrix
3990  , AlignmentFlag AF2 // Alignment flag of the right-hand side submatrix
3991  , bool SO2 // Storage order of the right-hand side submatrix
3992  , bool DF2 // Density flag of the right-hand side submatrix
3993  , size_t... CSAs2 > // Compile time submatrix arguments of the right-hand side submatrix
3994 inline bool isSame( const Submatrix<MT1,AF1,SO1,DF1,CSAs1...>& a,
3995  const Submatrix<MT2,AF2,SO2,DF2,CSAs2...>& b ) noexcept
3996 {
3997  return ( isSame( a.operand(), b.operand() ) &&
3998  ( a.row() == b.row() ) && ( a.column() == b.column() ) &&
3999  ( a.rows() == b.rows() ) && ( a.columns() == b.columns() ) );
4000 }
4002 //*************************************************************************************************
4003 
4004 
4005 //*************************************************************************************************
4044 template< InversionFlag IF // Inversion algorithm
4045  , typename MT // Type of the dense matrix
4046  , AlignmentFlag AF // Alignment flag
4047  , bool SO // Storage order
4048  , size_t... CSAs > // Compile time submatrix arguments
4049 inline DisableIf_< HasMutableDataAccess<MT> > invert( Submatrix<MT,AF,SO,true,CSAs...>& sm )
4050 {
4051  using RT = ResultType_< Submatrix<MT,AF,SO,true,CSAs...> >;
4052 
4055 
4056  RT tmp( sm );
4057  invert<IF>( tmp );
4058  sm = tmp;
4059 }
4061 //*************************************************************************************************
4062 
4063 
4064 //*************************************************************************************************
4080 template< typename MT // Type of the matrix
4081  , AlignmentFlag AF // Alignment flag
4082  , bool SO // Storage order
4083  , bool DF // Density flag
4084  , size_t... CSAs // Compile time submatrix arguments
4085  , typename ET > // Type of the element
4086 inline bool trySet( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4087 {
4088  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4089  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4090 
4091  return trySet( sm.operand(), sm.row()+i, sm.column()+j, value );
4092 }
4094 //*************************************************************************************************
4095 
4096 
4097 //*************************************************************************************************
4113 template< typename MT // Type of the matrix
4114  , AlignmentFlag AF // Alignment flag
4115  , bool SO // Storage order
4116  , bool DF // Density flag
4117  , size_t... CSAs // Compile time submatrix arguments
4118  , typename ET > // Type of the element
4119 inline bool tryAdd( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4120 {
4121  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4122  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4123 
4124  return tryAdd( sm.operand(), sm.row()+i, sm.column()+j, value );
4125 }
4127 //*************************************************************************************************
4128 
4129 
4130 //*************************************************************************************************
4146 template< typename MT // Type of the matrix
4147  , AlignmentFlag AF // Alignment flag
4148  , bool SO // Storage order
4149  , bool DF // Density flag
4150  , size_t... CSAs // Compile time submatrix arguments
4151  , typename ET > // Type of the element
4152 inline bool trySub( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4153 {
4154  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4155  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4156 
4157  return trySub( sm.operand(), sm.row()+i, sm.column()+j, value );
4158 }
4160 //*************************************************************************************************
4161 
4162 
4163 //*************************************************************************************************
4179 template< typename MT // Type of the matrix
4180  , AlignmentFlag AF // Alignment flag
4181  , bool SO // Storage order
4182  , bool DF // Density flag
4183  , size_t... CSAs // Compile time submatrix arguments
4184  , typename ET > // Type of the element
4185 inline bool tryMult( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t i, size_t j, const ET& value )
4186 {
4187  BLAZE_INTERNAL_ASSERT( i < sm.rows(), "Invalid row access index" );
4188  BLAZE_INTERNAL_ASSERT( j < sm.columns(), "Invalid column access index" );
4189 
4190  return tryMult( sm.operand(), sm.row()+i, sm.column()+j, value );
4191 }
4193 //*************************************************************************************************
4194 
4195 
4196 //*************************************************************************************************
4214 template< typename MT // Type of the matrix
4215  , AlignmentFlag AF // Alignment flag
4216  , bool SO // Storage order
4217  , bool DF // Density flag
4218  , size_t... CSAs // Compile time submatrix arguments
4219  , typename ET > // Type of the element
4221  tryMult( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t row, size_t column, size_t m, size_t n, const ET& value )
4222 {
4223  UNUSED_PARAMETER( column );
4224 
4225  BLAZE_INTERNAL_ASSERT( row <= (~sm).rows(), "Invalid row access index" );
4226  BLAZE_INTERNAL_ASSERT( column <= (~sm).columns(), "Invalid column access index" );
4227  BLAZE_INTERNAL_ASSERT( row + m <= (~sm).rows(), "Invalid number of rows" );
4228  BLAZE_INTERNAL_ASSERT( column + n <= (~sm).columns(), "Invalid number of columns" );
4229 
4230  return tryMult( sm.operand(), sm.row()+row, sm.column(), m, n, 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 tryDiv( 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 tryDiv( sm.operand(), sm.row()+i, sm.column()+j, value );
4264 }
4266 //*************************************************************************************************
4267 
4268 
4269 //*************************************************************************************************
4287 template< typename MT // Type of the matrix
4288  , AlignmentFlag AF // Alignment flag
4289  , bool SO // Storage order
4290  , bool DF // Density flag
4291  , size_t... CSAs // Compile time submatrix arguments
4292  , typename ET > // Type of the element
4294  tryDiv( const Submatrix<MT,AF,SO,DF,CSAs...>& sm, size_t row, size_t column, size_t m, size_t n, const ET& value )
4295 {
4296  UNUSED_PARAMETER( column );
4297 
4298  BLAZE_INTERNAL_ASSERT( row <= (~sm).rows(), "Invalid row access index" );
4299  BLAZE_INTERNAL_ASSERT( column <= (~sm).columns(), "Invalid column access index" );
4300  BLAZE_INTERNAL_ASSERT( row + m <= (~sm).rows(), "Invalid number of rows" );
4301  BLAZE_INTERNAL_ASSERT( column + n <= (~sm).columns(), "Invalid number of columns" );
4302 
4303  return tryDiv( sm.operand(), sm.row()+row, sm.column(), m, n, value );
4304 }
4306 //*************************************************************************************************
4307 
4308 
4309 //*************************************************************************************************
4325 template< typename MT // Type of the matrix
4326  , AlignmentFlag AF // Alignment flag
4327  , bool SO // Storage order
4328  , bool DF // Density flag
4329  , size_t... CSAs // Compile time submatrix arguments
4330  , typename VT // Type of the right-hand side vector
4331  , bool TF > // Transpose flag of the right-hand side vector
4332 inline bool tryAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4333  const Vector<VT,TF>& rhs, size_t row, size_t column )
4334 {
4335  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4336  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4337  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4338  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4339 
4340  return tryAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4341 }
4343 //*************************************************************************************************
4344 
4345 
4346 //*************************************************************************************************
4363 template< typename MT // Type of the matrix
4364  , AlignmentFlag AF // Alignment flag
4365  , bool SO // Storage order
4366  , bool DF // Density flag
4367  , size_t... CSAs // Compile time submatrix arguments
4368  , typename VT // Type of the right-hand side vector
4369  , bool TF > // Transpose flag of the right-hand side vector
4370 inline bool tryAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4371  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4372 {
4373  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4374  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4375  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4376  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4377 
4378  return tryAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4379  lhs.row() + row, lhs.column() + column );
4380 }
4382 //*************************************************************************************************
4383 
4384 
4385 //*************************************************************************************************
4401 template< typename MT1 // Type of the matrix
4402  , AlignmentFlag AF // Alignment flag
4403  , bool SO1 // Storage order
4404  , bool DF // Density flag
4405  , size_t... CSAs // Compile time submatrix arguments
4406  , typename MT2 // Type of the right-hand side matrix
4407  , bool SO2 > // Storage order of the right-hand side matrix
4408 inline bool tryAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4409  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4410 {
4411  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4412  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4413  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4414  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4415 
4416  return tryAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4417 }
4419 //*************************************************************************************************
4420 
4421 
4422 //*************************************************************************************************
4438 template< typename MT // Type of the matrix
4439  , AlignmentFlag AF // Alignment flag
4440  , bool SO // Storage order
4441  , bool DF // Density flag
4442  , size_t... CSAs // Compile time submatrix arguments
4443  , typename VT // Type of the right-hand side vector
4444  , bool TF > // Transpose flag of the right-hand side vector
4445 inline bool tryAddAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4446  const Vector<VT,TF>& rhs, size_t row, size_t column )
4447 {
4448  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4449  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4450  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4451  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4452 
4453  return tryAddAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4454 }
4456 //*************************************************************************************************
4457 
4458 
4459 //*************************************************************************************************
4477 template< typename MT // Type of the matrix
4478  , AlignmentFlag AF // Alignment flag
4479  , bool SO // Storage order
4480  , bool DF // Density flag
4481  , size_t... CSAs // Compile time submatrix arguments
4482  , typename VT // Type of the right-hand side vector
4483  , bool TF > // Transpose flag of the right-hand side vector
4484 inline bool tryAddAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4485  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4486 {
4487  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4488  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4489  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4490  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4491 
4492  return tryAddAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4493  lhs.row() + row, lhs.column() + column );
4494 }
4496 //*************************************************************************************************
4497 
4498 
4499 //*************************************************************************************************
4515 template< typename MT1 // Type of the matrix
4516  , AlignmentFlag AF // Alignment flag
4517  , bool SO1 // Storage order
4518  , bool DF // Density flag
4519  , size_t... CSAs // Compile time submatrix arguments
4520  , typename MT2 // Type of the right-hand side matrix
4521  , bool SO2 > // Storage order of the right-hand side matrix
4522 inline bool tryAddAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4523  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4524 {
4525  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4526  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4527  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4528  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4529 
4530  return tryAddAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4531 }
4533 //*************************************************************************************************
4534 
4535 
4536 //*************************************************************************************************
4552 template< typename MT // Type of the matrix
4553  , AlignmentFlag AF // Alignment flag
4554  , bool SO // Storage order
4555  , bool DF // Density flag
4556  , size_t... CSAs // Compile time submatrix arguments
4557  , typename VT // Type of the right-hand side vector
4558  , bool TF > // Transpose flag of the right-hand side vector
4559 inline bool trySubAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4560  const Vector<VT,TF>& rhs, size_t row, size_t column )
4561 {
4562  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4563  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4564  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4565  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4566 
4567  return trySubAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4568 }
4570 //*************************************************************************************************
4571 
4572 
4573 //*************************************************************************************************
4591 template< typename MT // Type of the matrix
4592  , AlignmentFlag AF // Alignment flag
4593  , bool SO // Storage order
4594  , bool DF // Density flag
4595  , size_t... CSAs // Compile time submatrix arguments
4596  , typename VT // Type of the right-hand side vector
4597  , bool TF > // Transpose flag of the right-hand side vector
4598 inline bool trySubAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4599  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4600 {
4601  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4602  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4603  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4604  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4605 
4606  return trySubAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4607  lhs.row() + row, lhs.column() + column );
4608 }
4610 //*************************************************************************************************
4611 
4612 
4613 //*************************************************************************************************
4629 template< typename MT1 // Type of the matrix
4630  , AlignmentFlag AF // Alignment flag
4631  , bool SO1 // Storage order
4632  , bool DF // Density flag
4633  , size_t... CSAs // Compile time submatrix arguments
4634  , typename MT2 // Type of the right-hand side matrix
4635  , bool SO2 > // Storage order of the right-hand side matrix
4636 inline bool trySubAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4637  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4638 {
4639  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4640  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4641  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4642  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4643 
4644  return trySubAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4645 }
4647 //*************************************************************************************************
4648 
4649 
4650 //*************************************************************************************************
4666 template< typename MT // Type of the matrix
4667  , AlignmentFlag AF // Alignment flag
4668  , bool SO // Storage order
4669  , bool DF // Density flag
4670  , size_t... CSAs // Compile time submatrix arguments
4671  , typename VT // Type of the right-hand side vector
4672  , bool TF > // Transpose flag of the right-hand side vector
4673 inline bool tryMultAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4674  const Vector<VT,TF>& rhs, size_t row, size_t column )
4675 {
4676  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4677  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4678  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4679  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4680 
4681  return tryMultAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4682 }
4684 //*************************************************************************************************
4685 
4686 
4687 //*************************************************************************************************
4705 template< typename MT // Type of the matrix
4706  , AlignmentFlag AF // Alignment flag
4707  , bool SO // Storage order
4708  , bool DF // Density flag
4709  , size_t... CSAs // Compile time submatrix arguments
4710  , typename VT // Type of the right-hand side vector
4711  , bool TF > // Transpose flag of the right-hand side vector
4712 inline bool tryMultAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4713  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4714 {
4715  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4716  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4717  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4718  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4719 
4720  return tryMultAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4721  lhs.row() + row, lhs.column() + column );
4722 }
4724 //*************************************************************************************************
4725 
4726 
4727 //*************************************************************************************************
4743 template< typename MT1 // Type of the matrix
4744  , AlignmentFlag AF // Alignment flag
4745  , bool SO1 // Storage order
4746  , bool DF // Density flag
4747  , size_t... CSAs // Compile time submatrix arguments
4748  , typename MT2 // Type of the right-hand side matrix
4749  , bool SO2 > // Storage order of the right-hand side matrix
4750 inline bool trySchurAssign( const Submatrix<MT1,AF,SO1,DF,CSAs...>& lhs,
4751  const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4752 {
4753  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4754  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4755  BLAZE_INTERNAL_ASSERT( row + (~rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4756  BLAZE_INTERNAL_ASSERT( column + (~rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4757 
4758  return trySchurAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4759 }
4761 //*************************************************************************************************
4762 
4763 
4764 //*************************************************************************************************
4780 template< typename MT // Type of the matrix
4781  , AlignmentFlag AF // Alignment flag
4782  , bool SO // Storage order
4783  , bool DF // Density flag
4784  , size_t... CSAs // Compile time submatrix arguments
4785  , typename VT // Type of the right-hand side vector
4786  , bool TF > // Transpose flag of the right-hand side vector
4787 inline bool tryDivAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4788  const Vector<VT,TF>& rhs, size_t row, size_t column )
4789 {
4790  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4791  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4792  BLAZE_INTERNAL_ASSERT( TF || ( row + (~rhs).size() <= lhs.rows() ), "Invalid number of rows" );
4793  BLAZE_INTERNAL_ASSERT( !TF || ( column + (~rhs).size() <= lhs.columns() ), "Invalid number of columns" );
4794 
4795  return tryDivAssign( lhs.operand(), ~rhs, lhs.row() + row, lhs.column() + column );
4796 }
4798 //*************************************************************************************************
4799 
4800 
4801 //*************************************************************************************************
4819 template< typename MT // Type of the matrix
4820  , AlignmentFlag AF // Alignment flag
4821  , bool SO // Storage order
4822  , bool DF // Density flag
4823  , size_t... CSAs // Compile time submatrix arguments
4824  , typename VT // Type of the right-hand side vector
4825  , bool TF > // Transpose flag of the right-hand side vector
4826 inline bool tryDivAssign( const Submatrix<MT,AF,SO,DF,CSAs...>& lhs,
4827  const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4828 {
4829  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4830  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4831  BLAZE_INTERNAL_ASSERT( row + (~rhs).size() <= lhs.rows(), "Invalid number of rows" );
4832  BLAZE_INTERNAL_ASSERT( column + (~rhs).size() <= lhs.columns(), "Invalid number of columns" );
4833 
4834  return tryDivAssign( lhs.operand(), ~rhs, band + ptrdiff_t( lhs.column() - lhs.row() ),
4835  lhs.row() + row, lhs.column() + column );
4836 }
4838 //*************************************************************************************************
4839 
4840 
4841 //*************************************************************************************************
4856 template< typename MT // Type of the matrix
4857  , AlignmentFlag AF // Alignment flag
4858  , bool SO // Storage order
4859  , bool DF // Density flag
4860  , size_t I // Index of the first row
4861  , size_t J // Index of the first column
4862  , size_t M // Number of rows
4863  , size_t N > // Number of columns
4864 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF,I,J,M,N>& dm )
4865 {
4866  return submatrix<AF,I,J,M,N>( derestrict( dm.operand() ), unchecked );
4867 }
4869 //*************************************************************************************************
4870 
4871 
4872 //*************************************************************************************************
4887 template< typename MT // Type of the matrix
4888  , AlignmentFlag AF // Alignment flag
4889  , bool SO // Storage order
4890  , bool DF // Density flag
4891  , size_t I // Index of the first row
4892  , size_t J // Index of the first column
4893  , size_t M // Number of rows
4894  , size_t N > // Number of columns
4895 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF,I,J,M,N>&& dm )
4896 {
4897  return submatrix<AF,I,J,M,N>( derestrict( dm.operand() ), unchecked );
4898 }
4900 //*************************************************************************************************
4901 
4902 
4903 //*************************************************************************************************
4918 template< typename MT // Type of the matrix
4919  , AlignmentFlag AF // Alignment flag
4920  , bool SO // Storage order
4921  , bool DF > // Density flag
4922 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF>& dm )
4923 {
4924  return submatrix<AF>( derestrict( dm.operand() ), dm.row(), dm.column(), dm.rows(), dm.columns(), unchecked );
4925 }
4927 //*************************************************************************************************
4928 
4929 
4930 //*************************************************************************************************
4945 template< typename MT // Type of the matrix
4946  , AlignmentFlag AF // Alignment flag
4947  , bool SO // Storage order
4948  , bool DF > // Density flag
4949 inline decltype(auto) derestrict( Submatrix<MT,AF,SO,DF>&& dm )
4950 {
4951  return submatrix<AF>( derestrict( dm.operand() ), dm.row(), dm.column(), dm.rows(), dm.columns(), unchecked );
4952 }
4954 //*************************************************************************************************
4955 
4956 
4957 
4958 
4959 //=================================================================================================
4960 //
4961 // SIZE SPECIALIZATIONS
4962 //
4963 //=================================================================================================
4964 
4965 //*************************************************************************************************
4967 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
4968 struct Size< Submatrix<MT,AF,SO,DF,I,J,M,N>, 0UL >
4969  : public PtrdiffT<M>
4970 {};
4971 
4972 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
4973 struct Size< Submatrix<MT,AF,SO,DF,I,J,M,N>, 1UL >
4974  : public PtrdiffT<N>
4975 {};
4977 //*************************************************************************************************
4978 
4979 
4980 
4981 
4982 //=================================================================================================
4983 //
4984 // ISRESTRICTED SPECIALIZATIONS
4985 //
4986 //=================================================================================================
4987 
4988 //*************************************************************************************************
4990 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs >
4991 struct IsRestricted< Submatrix<MT,AF,SO,DF,CSAs...> >
4992  : public IsRestricted<MT>
4993 {};
4995 //*************************************************************************************************
4996 
4997 
4998 
4999 
5000 //=================================================================================================
5001 //
5002 // HASCONSTDATAACCESS SPECIALIZATIONS
5003 //
5004 //=================================================================================================
5005 
5006 //*************************************************************************************************
5008 template< typename MT, AlignmentFlag AF, bool SO, size_t... CSAs >
5009 struct HasConstDataAccess< Submatrix<MT,AF,SO,true,CSAs...> >
5010  : public HasConstDataAccess<MT>
5011 {};
5013 //*************************************************************************************************
5014 
5015 
5016 
5017 
5018 //=================================================================================================
5019 //
5020 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5021 //
5022 //=================================================================================================
5023 
5024 //*************************************************************************************************
5026 template< typename MT, AlignmentFlag AF, bool SO, size_t... CSAs >
5027 struct HasMutableDataAccess< Submatrix<MT,AF,SO,true,CSAs...> >
5028  : public HasMutableDataAccess<MT>
5029 {};
5031 //*************************************************************************************************
5032 
5033 
5034 
5035 
5036 //=================================================================================================
5037 //
5038 // ISALIGNED SPECIALIZATIONS
5039 //
5040 //=================================================================================================
5041 
5042 //*************************************************************************************************
5044 template< typename MT, bool SO, size_t... CSAs >
5045 struct IsAligned< Submatrix<MT,aligned,SO,true,CSAs...> >
5046  : public TrueType
5047 {};
5049 //*************************************************************************************************
5050 
5051 
5052 
5053 
5054 //=================================================================================================
5055 //
5056 // ISCONTIGUOUS SPECIALIZATIONS
5057 //
5058 //=================================================================================================
5059 
5060 //*************************************************************************************************
5062 template< typename MT, AlignmentFlag AF, bool SO, size_t... CSAs >
5063 struct IsContiguous< Submatrix<MT,AF,SO,true,CSAs...> >
5064  : public IsContiguous<MT>
5065 {};
5067 //*************************************************************************************************
5068 
5069 
5070 
5071 
5072 //=================================================================================================
5073 //
5074 // ISSYMMETRIC SPECIALIZATIONS
5075 //
5076 //=================================================================================================
5077 
5078 //*************************************************************************************************
5080 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5081 struct IsSymmetric< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5082  : public BoolConstant< ( IsSymmetric<MT>::value && I == J && M == N ) >
5083 {};
5085 //*************************************************************************************************
5086 
5087 
5088 
5089 
5090 //=================================================================================================
5091 //
5092 // ISHERMITIAN SPECIALIZATIONS
5093 //
5094 //=================================================================================================
5095 
5096 //*************************************************************************************************
5098 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5099 struct IsHermitian< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5100  : public BoolConstant< ( IsHermitian<MT>::value && I == J && M == N ) >
5101 {};
5103 //*************************************************************************************************
5104 
5105 
5106 
5107 
5108 //=================================================================================================
5109 //
5110 // ISLOWER SPECIALIZATIONS
5111 //
5112 //=================================================================================================
5113 
5114 //*************************************************************************************************
5116 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5117 struct IsLower< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5118  : public BoolConstant< ( IsLower<MT>::value && I == J && M == N ) ||
5119  ( IsStrictlyLower<MT>::value && I == J+1UL && M == N ) >
5120 {};
5122 //*************************************************************************************************
5123 
5124 
5125 
5126 
5127 //=================================================================================================
5128 //
5129 // ISUNILOWER SPECIALIZATIONS
5130 //
5131 //=================================================================================================
5132 
5133 //*************************************************************************************************
5135 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5136 struct IsUniLower< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5137  : public BoolConstant< ( IsUniLower<MT>::value && I == J && M == N ) >
5138 {};
5140 //*************************************************************************************************
5141 
5142 
5143 
5144 
5145 //=================================================================================================
5146 //
5147 // ISSTRICTLYLOWER SPECIALIZATIONS
5148 //
5149 //=================================================================================================
5150 
5151 //*************************************************************************************************
5153 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5154 struct IsStrictlyLower< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5155  : public BoolConstant< ( IsLower<MT>::value && I < J && M == N ) ||
5156  ( IsStrictlyLower<MT>::value && I == J && M == N ) >
5157 {};
5159 //*************************************************************************************************
5160 
5161 
5162 
5163 
5164 //=================================================================================================
5165 //
5166 // ISUPPER SPECIALIZATIONS
5167 //
5168 //=================================================================================================
5169 
5170 //*************************************************************************************************
5172 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5173 struct IsUpper< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5174  : public BoolConstant< ( IsUpper<MT>::value && I == J && M == N ) ||
5175  ( IsStrictlyUpper<MT>::value && I+1UL == J && M == N ) >
5176 {};
5178 //*************************************************************************************************
5179 
5180 
5181 
5182 
5183 //=================================================================================================
5184 //
5185 // ISUNIUPPER SPECIALIZATIONS
5186 //
5187 //=================================================================================================
5188 
5189 //*************************************************************************************************
5191 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5192 struct IsUniUpper< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5193  : public BoolConstant< ( IsUniUpper<MT>::value && I == J && M == N ) >
5194 {};
5196 //*************************************************************************************************
5197 
5198 
5199 
5200 
5201 //=================================================================================================
5202 //
5203 // ISSTRICTLYUPPER SPECIALIZATIONS
5204 //
5205 //=================================================================================================
5206 
5207 //*************************************************************************************************
5209 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t I, size_t J, size_t M, size_t N >
5210 struct IsStrictlyUpper< Submatrix<MT,AF,SO,DF,I,J,M,N> >
5211  : public BoolConstant< ( IsUpper<MT>::value && I > J && M == N ) ||
5212  ( IsStrictlyUpper<MT>::value && I == J && M == N ) >
5213 {};
5215 //*************************************************************************************************
5216 
5217 
5218 
5219 
5220 //=================================================================================================
5221 //
5222 // SUBMATRIXTRAIT SPECIALIZATIONS
5223 //
5224 //=================================================================================================
5225 
5226 //*************************************************************************************************
5228 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs1, size_t... CSAs2 >
5229 struct SubmatrixTrait< Submatrix<MT,AF,SO,DF,CSAs1...>, CSAs2... >
5230 {
5231  using Type = SubmatrixTrait_< ResultType_< Submatrix<MT,AF,SO,DF,CSAs1...> >, CSAs2... >;
5232 };
5234 //*************************************************************************************************
5235 
5236 
5237 
5238 
5239 //=================================================================================================
5240 //
5241 // ROWTRAIT SPECIALIZATIONS
5242 //
5243 //=================================================================================================
5244 
5245 //*************************************************************************************************
5247 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs, size_t... CRAs >
5248 struct RowTrait< Submatrix<MT,AF,SO,DF,CSAs...>, CRAs... >
5249 {
5250  using Type = RowTrait_< ResultType_< Submatrix<MT,AF,SO,DF,CSAs...> >, CRAs... >;
5251 };
5253 //*************************************************************************************************
5254 
5255 
5256 
5257 
5258 //=================================================================================================
5259 //
5260 // ROWSTRAIT SPECIALIZATIONS
5261 //
5262 //=================================================================================================
5263 
5264 //*************************************************************************************************
5266 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs, size_t... CRAs >
5267 struct RowsTrait< Submatrix<MT,AF,SO,DF,CSAs...>, CRAs... >
5268 {
5269  using Type = RowsTrait_< ResultType_< Submatrix<MT,AF,SO,DF,CSAs...> >, CRAs... >;
5270 };
5272 //*************************************************************************************************
5273 
5274 
5275 
5276 
5277 //=================================================================================================
5278 //
5279 // COLUMNTRAIT SPECIALIZATIONS
5280 //
5281 //=================================================================================================
5282 
5283 //*************************************************************************************************
5285 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs, size_t... CCAs >
5286 struct ColumnTrait< Submatrix<MT,AF,SO,DF,CSAs...>, CCAs... >
5287 {
5288  using Type = ColumnTrait_< ResultType_< Submatrix<MT,AF,SO,DF,CSAs...> >, CCAs... >;
5289 };
5291 //*************************************************************************************************
5292 
5293 
5294 
5295 
5296 //=================================================================================================
5297 //
5298 // COLUMNSTRAIT SPECIALIZATIONS
5299 //
5300 //=================================================================================================
5301 
5302 //*************************************************************************************************
5304 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs, size_t... CCAs >
5305 struct ColumnsTrait< Submatrix<MT,AF,SO,DF,CSAs...>, CCAs... >
5306 {
5307  using Type = ColumnsTrait_< ResultType_< Submatrix<MT,AF,SO,DF,CSAs...> >, CCAs... >;
5308 };
5310 //*************************************************************************************************
5311 
5312 
5313 
5314 
5315 //=================================================================================================
5316 //
5317 // BANDTRAIT SPECIALIZATIONS
5318 //
5319 //=================================================================================================
5320 
5321 //*************************************************************************************************
5323 template< typename MT, AlignmentFlag AF, bool SO, bool DF, size_t... CSAs, ptrdiff_t... CBAs >
5324 struct BandTrait< Submatrix<MT,AF,SO,DF,CSAs...>, CBAs... >
5325 {
5326  using Type = BandTrait_< ResultType_< Submatrix<MT,AF,SO,DF,CSAs...> >, CBAs... >;
5327 };
5329 //*************************************************************************************************
5330 
5331 } // namespace blaze
5332 
5333 #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
Pointer difference type of the Blaze library.
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:131
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
Base class for all vector/matrix multiplication expression templates.The TVecMatMultExpr class serves...
Definition: TVecMatMultExpr.h:67
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:1214
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1469
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1386
Base class for all binary matrix map expression templates.The MatMatMapExpr class serves as a tag for...
Definition: MatMatMapExpr.h:66
Header file for the implementation of the RowData class template.
Compile time check for low-level access to constant data.This type trait tests whether the given data...
Definition: HasConstDataAccess.h:75
#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
BLAZE_ALWAYS_INLINE 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:949
Header file for basic type definitions.
Base class for all matrix serial evaluation expression templates.The MatSerialExpr class serves as a ...
Definition: MatSerialExpr.h:67
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:109
Base class for all matrix/scalar division expression templates.The MatScalarDivExpr class serves as a...
Definition: MatScalarDivExpr.h:66
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:108
Header file for the serial shim.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
Header file for the MatTransExpr base class.
Iterator end() noexcept
Returns an iterator just past the last element of the small vector.
Definition: SmallVector.h:620
Header file for the dense matrix inversion flags.
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
Auxiliary class template for the data members of the Column class.The auxiliary ColumnData class temp...
Definition: ColumnData.h:64
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1299
Implementation of a dynamic vector with small vector optimization.The SmallVector class template is a...
Definition: SmallVector.h:80
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Base class for all matrix/scalar multiplication expression templates.The MatScalarMultExpr class serv...
Definition: MatScalarMultExpr.h:67
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
Header file for the MatEvalExpr base class.
Auxiliary class template for the data members of the Subvector class.The auxiliary SubvectorData clas...
Definition: SubvectorData.h:64
Header file for the MatMatMultExpr base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
Header file for the decltype(auto) workaround.
#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
typename SubmatrixTrait< MT, CSAs... >::Type SubmatrixTrait_
Auxiliary alias declaration for the SubmatrixTrait type trait.The SubmatrixTrait_ alias declaration p...
Definition: SubmatrixTrait.h:145
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
typename RowTrait< MT, CRAs... >::Type RowTrait_
Auxiliary alias declaration for the RowTrait type trait.The RowTrait_ alias declaration provides a co...
Definition: RowTrait.h:145
Base template for the RowsTrait class.
Definition: RowsTrait.h:109
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Header file for the band trait.
Compile time check for data types with restricted data access.This type trait tests whether the given...
Definition: IsRestricted.h:82
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
Pointer data() noexcept
Low-level data access to the vector elements.
Definition: SmallVector.h:538
void invert(const HermitianProxy< MT > &proxy)
In-place inversion of the represented element.
Definition: HermitianProxy.h:772
Submatrix specialization for dense matrices.
Header file for the MatMapExpr base class.
Base template for the RowTrait class.
Definition: RowTrait.h:109
Header file for the implementation of the Subvector view.
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
Compile time check for the memory layout of data types.This type trait tests whether the given data t...
Definition: IsContiguous.h:86
Headerfile for the generic max algorithm.
typename ColumnTrait< MT, CCAs... >::Type ColumnTrait_
Auxiliary alias declaration for the ColumnTrait type trait.The ColumnTrait_ alias declaration provide...
Definition: ColumnTrait.h:144
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
typename ColumnsTrait< MT, CCAs... >::Type ColumnsTrait_
Auxiliary alias declaration for the ColumnsTrait type trait.The ColumnsTrait_ alias declaration provi...
Definition: ColumnsTrait.h:145
Base class for all matrix/matrix subtraction expression templates.The MatMatSubExpr class serves as a...
Definition: MatMatSubExpr.h:67
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.
Header file for the implementation of the Submatrix base template.
Base class for all matrix/matrix addition expression templates.The MatMatAddExpr class serves as a ta...
Definition: MatMatAddExpr.h:66
Header file for the MatMatSubExpr base class.
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:506
Base class for all unary matrix map expression templates.The MatMapExpr class serves as a tag for all...
Definition: MatMapExpr.h:66
Base class for all matrix/vector multiplication expression templates.The MatVecMultExpr class serves ...
Definition: MatVecMultExpr.h:67
Implementation of a type list.The TypeList class template represents a list of data types of arbitrar...
Definition: TypeList.h:119
decltype(auto) eval(const DenseMatrix< MT, SO > &dm)
Forces the evaluation of the given dense matrix expression dm.
Definition: DMatEvalExpr.h:794
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
typename RemoveReference< T >::Type RemoveReference_
Auxiliary alias declaration for the RemoveReference type trait.The RemoveReference_ alias declaration...
Definition: RemoveReference.h:95
Submatrix specialization for sparse matrices.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
BLAZE_ALWAYS_INLINE 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:430
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
typename BandTrait< MT, CBAs... >::Type BandTrait_
Auxiliary alias declaration for the BandTrait type trait.The BandTrait_ alias declaration provides a ...
Definition: BandTrait.h:145
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:608
decltype(auto) band(Matrix< MT, SO > &matrix, RBAs... args)
Creating a view on a specific band of the given matrix.
Definition: Band.h:134
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
typename RowsTrait< MT, CRAs... >::Type RowsTrait_
Auxiliary alias declaration for the RowsTrait type trait.The RowsTrait_ alias declaration provides a ...
Definition: RowsTrait.h:145
Header file for the HasConstDataAccess type trait.
Header file for the DeclExpr base class.
Base class for all matrix/matrix multiplication expression templates.The MatMatMultExpr class serves ...
Definition: MatMatMultExpr.h:67
Header file for the Matrix base class.
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1641
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:179
Header file for the MatScalarMultExpr base class.
Base class for all Schur product expression templates.The SchurExpr class serves as a tag for all exp...
Definition: SchurExpr.h:66
Header file for run time assertion macros.
Header file for the Unique class template.
Header file for the submatrix trait.
Header file for the IsContiguous type trait.
Header file for the columns trait.
Header file for the SchurExpr base class.
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:131
Compile time integral constant wrapper for ptrdiff_t.The PtrdiffT class template represents an integr...
Definition: PtrdiffT.h:72
Base class for all matrix evaluation expression templates.The MatEvalExpr class serves as a tag for a...
Definition: MatEvalExpr.h:66
#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:919
Header file for the column trait.
Header file for the isDefault shim.
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
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:816
Base class for all matrix transposition expression templates.The MatTransExpr class serves as a tag f...
Definition: MatTransExpr.h:66
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:841
#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.
Header file for the RemoveReference type trait.
Base class for all outer product expression templates.The VecTVecMultExpr class serves as a tag for a...
Definition: VecTVecMultExpr.h:67
Header file for the rows trait.
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
Auxiliary class template for the data members of the Row class.The auxiliary RowData class template r...
Definition: RowData.h:64
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
Base template for the ColumnsTrait class.
Definition: ColumnsTrait.h:109
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:177
Auxiliary class template for the data members of the Submatrix class.The auxiliary SubmatrixData clas...
Definition: SubmatrixData.h:64
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Header file for the MatMatMapExpr base class.
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
Iterator begin() noexcept
Returns an iterator to the first element of the small vector.
Definition: SmallVector.h:572
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:1554
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
Header file for the IsUpper type trait.
Header file for the implementation of the ColumnData class template.
Header file for the MatScalarDivExpr base class.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Searching a type list.The Contains class can be used to search the type list for a particular type Ty...
Definition: Contains.h:78
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 TrueType type/value trait base class.
Base template for the BandTrait class.
Definition: BandTrait.h:109
typename T::BaseType BaseType_
Alias declaration for nested BaseType type definitions.The BaseType_ alias declaration provides a con...
Definition: Aliases.h:63
Header file for the function trace functionality.
Template for the blaze::checked and blaze::unchecked instances.blaze::Check is the template for the b...
Definition: Check.h:56
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:1134