86 [[nodiscard]] std::size_t
order() const noexcept {
return diagonal.size(); }
237 [[nodiscard]] std::size_t
order() const noexcept {
return diagonal.size(); }
482 std::vector<uni20::complex<Real>>
alpha;
492 std::vector<uni20::complex<Real>>
alpha;
539 std::vector<uni20::complex<Real>>
alpha;
542 std::vector<RealSchurBlock<Real>>
blocks;
609 case MatrixFill::Upper:
611 case MatrixFill::Lower:
613 case MatrixFill::All:
614 throw std::invalid_argument(
"dense symmetric LAPACK operation requires an upper or lower triangle selector");
616 throw std::invalid_argument(
"dense symmetric LAPACK operation received an unknown triangle selector");
619template <uni20::LapackReal Scalar>
620Scalar symmetric_matrix_one_norm(detail::ColumnMajorLapackMatrix<Scalar>
const& matrix,
MatrixFill triangle)
622 if (!std::cmp_equal(matrix.rows(), matrix.cols()))
624 throw std::invalid_argument(
"symmetric_matrix_one_norm requires a square matrix");
626 if (triangle == MatrixFill::All)
628 throw std::invalid_argument(
"symmetric_matrix_one_norm requires an upper or lower triangle selector");
637 if (triangle == MatrixFill::Upper)
651template <
typename Scalar>
652void mirror_selected_symmetric_triangle(detail::ColumnMajorLapackMatrix<Scalar>& matrix,
MatrixFill triangle)
654 if (triangle == MatrixFill::All)
656 throw std::invalid_argument(
"symmetric triangle mirroring requires an upper or lower triangle selector");
662 if (triangle == MatrixFill::Upper &&
row > col)
664 matrix[
row, col] = matrix[col,
row];
666 if (triangle == MatrixFill::Lower &&
row < col)
668 matrix[
row, col] = matrix[col,
row];
674template <uni20::LapackReal Scalar>
676checked_symmetric_indefinite_pivots(RealSymmetricIndefiniteFactorization<Scalar>
const& factorization)
678 std::size_t
const n =
static_cast<std::size_t
>(factorization.factors.rows());
679 std::vector<blas_int> pivots(n);
680 for (std::size_t index = 0; index < n; ++index)
682 int const pivot = factorization.pivot_blocks[index];
683 std::size_t
const pivot_magnitude =
684 pivot < 0 ? static_cast<std::size_t>(-(pivot + 1)) + std::size_t{1} :
static_cast<std::size_t
>(pivot);
685 if (pivot_magnitude == 0 || pivot_magnitude > n)
687 throw std::invalid_argument(
"symmetric-indefinite factorization has an out-of-range pivot block");
689 pivots[index] =
static_cast<blas_int
>(pivot);
705 throw std::invalid_argument(
"dense real LAPACK operation received an unknown transpose selector");
717 throw std::invalid_argument(
"dense real LAPACK operation received an unknown side selector");
733 throw std::invalid_argument(
"dense real LAPACK operation received an unknown balance job");
737template <uni20::LapackReal Scalar>
740 if (matrix.
rows() == 0 || matrix.
cols() == 0)
745 blas_int
const rows = detail::checked_blas_int(matrix.
rows());
746 blas_int
const cols = detail::checked_blas_int(matrix.
cols());
747 blas_int
const lda = std::max<blas_int>(1, rows);
748 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, rows)),
Scalar{});
759template <uni20::LapackReal Scalar>
763 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
765 throw std::invalid_argument(
"real_symmetric_matrix_norm requires a square matrix");
767 if (matrix.
rows() == 0)
772 blas_int
const order = detail::checked_blas_int(matrix.
rows());
773 blas_int
const lda = std::max<blas_int>(1, order);
774 char const uplo = detail::lapack_uplo(triangle);
775 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, order)),
Scalar{});
789template <uni20::LapackReal Scalar>
791 MatrixFill triangle = MatrixFill::Upper,
bool unit_diagonal =
false)
793 if (matrix.
rows() == 0 || matrix.
cols() == 0)
798 blas_int
const rows = detail::checked_blas_int(matrix.
rows());
799 blas_int
const cols = detail::checked_blas_int(matrix.
cols());
800 blas_int
const lda = std::max<blas_int>(1, rows);
801 char const uplo = detail::lapack_uplo(triangle);
802 char const diag = unit_diagonal ?
'U' :
'N';
803 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, rows)),
Scalar{});
816template <uni20::LapackReal Scalar>
818 std::size_t lower_bandwidth, std::size_t upper_bandwidth)
820 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
822 throw std::invalid_argument(
"real_general_band_from_dense requires a square matrix");
825 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
832 for (std::size_t col = 0; col < n; ++col)
834 std::size_t
const first_row = col > upper_bandwidth ? col - upper_bandwidth : 0;
835 std::size_t
const last_row = std::min(n - 1, col + lower_bandwidth);
836 for (std::size_t
row = first_row;
row <= last_row; ++
row)
838 std::size_t
const band_row = lower_bandwidth + upper_bandwidth +
row - col;
839 result.
storage[band_row, col] = matrix[
row, col];
853template <uni20::LapackReal Scalar>
856 if (band_matrix.
order == 0)
860 if (!std::cmp_equal(band_matrix.
storage.cols(), band_matrix.
order) ||
863 throw std::invalid_argument(
"real_general_band_matrix_norm received inconsistent band storage");
866 blas_int
const n = detail::checked_blas_int(band_matrix.
order);
867 blas_int
const kl = detail::checked_blas_int(band_matrix.
lower_bandwidth);
868 blas_int
const ku = detail::checked_blas_int(band_matrix.
upper_bandwidth);
869 blas_int
const ldab = detail::checked_blas_int(band_matrix.
storage.rows());
870 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, n)),
Scalar{});
882template <uni20::LapackReal Scalar>
883detail::ColumnMajorLapackMatrix<Scalar>
887 if (!std::cmp_equal(coefficients.
storage.cols(), coefficients.
order) ||
890 throw std::invalid_argument(
"real_general_band_solve received inconsistent band storage");
892 if (!std::cmp_equal(right_hand_sides.
rows(), coefficients.
order))
894 throw std::invalid_argument(
"real_general_band_solve received incompatible right-hand sides");
896 if (coefficients.
order == 0 || right_hand_sides.
cols() == 0)
898 return right_hand_sides;
901 blas_int
const n = detail::checked_blas_int(coefficients.
order);
902 blas_int
const kl = detail::checked_blas_int(coefficients.
lower_bandwidth);
903 blas_int
const ku = detail::checked_blas_int(coefficients.
upper_bandwidth);
904 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
905 blas_int
const ldab = detail::checked_blas_int(coefficients.
storage.rows());
906 std::vector<blas_int> pivots(coefficients.
order);
908 return right_hand_sides;
915template <uni20::LapackReal Scalar>
918 if (!std::cmp_equal(matrix.
storage.cols(), matrix.
order) ||
921 throw std::invalid_argument(
"real_general_band_factorization received inconsistent band storage");
925 result.
factors = std::move(matrix);
933 blas_int
const n = detail::checked_blas_int(result.
factors.order);
934 blas_int
const kl = detail::checked_blas_int(result.
factors.lower_bandwidth);
935 blas_int
const ku = detail::checked_blas_int(result.
factors.upper_bandwidth);
936 blas_int
const ldab = detail::checked_blas_int(result.
factors.storage.rows());
937 std::vector<blas_int> pivots(result.
factors.order);
939 for (std::size_t index = 0; index < result.
factors.order; ++index)
941 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > result.
factors.order)
943 throw std::runtime_error(
"LAPACK gbtrf returned an invalid row pivot");
945 result.
pivot_rows[index] =
static_cast<std::size_t
>(pivots[index] - 1);
956template <uni20::LapackReal Scalar>
957detail::ColumnMajorLapackMatrix<Scalar>
962 if (!std::cmp_equal(factorization.
factors.storage.cols(), factorization.
factors.order) ||
963 std::cmp_less(factorization.
factors.storage.rows(),
964 2 * factorization.
factors.lower_bandwidth + factorization.
factors.upper_bandwidth + 1))
966 throw std::invalid_argument(
"real_general_band_solve received inconsistent band factors");
970 throw std::invalid_argument(
"real_general_band_solve received inconsistent pivot metadata");
972 if (!std::cmp_equal(right_hand_sides.
rows(), factorization.
factors.order))
974 throw std::invalid_argument(
"real_general_band_solve received incompatible right-hand sides");
976 if (factorization.
factors.order == 0 || right_hand_sides.
cols() == 0)
978 return right_hand_sides;
982 std::vector<blas_int> pivots(factorization.
factors.order);
983 for (std::size_t index = 0; index < factorization.
factors.order; ++index)
987 throw std::invalid_argument(
"real_general_band_solve received an out-of-range row pivot");
989 pivots[index] = detail::checked_blas_int(factorization.
pivot_rows[index] + 1);
992 blas_int
const n = detail::checked_blas_int(factorization.
factors.order);
993 blas_int
const kl = detail::checked_blas_int(factorization.
factors.lower_bandwidth);
994 blas_int
const ku = detail::checked_blas_int(factorization.
factors.upper_bandwidth);
995 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
996 blas_int
const ldab = detail::checked_blas_int(factors.
rows());
997 char const trans = detail::lapack_transpose(transpose);
999 return right_hand_sides;
1008template <uni20::LapackReal Scalar>
1009RealGeneralTridiagonalMatrix<Scalar>
1012 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
1014 throw std::invalid_argument(
"real_general_tridiagonal_from_dense requires a square matrix");
1019 if (matrix.
rows() > 0)
1026 result.
diagonal[index] = matrix[index, index];
1027 if (index + 1 < matrix.
rows())
1042template <uni20::LapackReal Scalar>
1043detail::ColumnMajorLapackMatrix<Scalar>
1047 std::size_t
const order = coefficients.
order();
1048 if (coefficients.
lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1049 coefficients.
upper_diagonal.size() != (order == 0 ? 0 : order - 1))
1051 throw std::invalid_argument(
"real_general_tridiagonal_solve received inconsistent tridiagonal storage");
1053 if (!std::cmp_equal(right_hand_sides.
rows(), order))
1055 throw std::invalid_argument(
"real_general_tridiagonal_solve received incompatible right-hand sides");
1057 if (order == 0 || right_hand_sides.
cols() == 0)
1059 return right_hand_sides;
1062 blas_int
const n = detail::checked_blas_int(order);
1063 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
1070 return right_hand_sides;
1077template <uni20::LapackReal Scalar>
1078RealGeneralTridiagonalFactorization<Scalar>
1081 std::size_t
const order = matrix.
order();
1082 if (matrix.
lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1085 throw std::invalid_argument(
"real_general_tridiagonal_factorization received inconsistent tridiagonal storage");
1089 result.
factors = std::move(matrix);
1098 blas_int
const n = detail::checked_blas_int(order);
1099 std::vector<blas_int> pivots(order);
1101 result.
factors.lower_diagonal.empty() ? result.
factors.diagonal.data() : result.
factors.lower_diagonal.data();
1103 result.
factors.upper_diagonal.empty() ? result.
factors.diagonal.data() : result.
factors.upper_diagonal.data();
1104 Scalar* second_upper_diagonal =
1108 for (std::size_t index = 0; index < order; ++index)
1110 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > order)
1112 throw std::runtime_error(
"LAPACK gttrf returned an invalid row pivot");
1114 result.
pivot_rows[index] =
static_cast<std::size_t
>(pivots[index] - 1);
1125template <uni20::LapackReal Scalar>
1126detail::ColumnMajorLapackMatrix<Scalar>
1131 std::size_t
const order = factorization.
factors.order();
1132 if (factorization.
factors.lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1133 factorization.
factors.upper_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1136 throw std::invalid_argument(
"real_general_tridiagonal_solve received inconsistent tridiagonal factors");
1138 if (factorization.
pivot_rows.size() != order)
1140 throw std::invalid_argument(
"real_general_tridiagonal_solve received inconsistent pivot metadata");
1142 if (!std::cmp_equal(right_hand_sides.
rows(), order))
1144 throw std::invalid_argument(
"real_general_tridiagonal_solve received incompatible right-hand sides");
1146 if (order == 0 || right_hand_sides.
cols() == 0)
1148 return right_hand_sides;
1151 auto lower_diagonal_values = factorization.
factors.lower_diagonal;
1152 auto diagonal_values = factorization.
factors.diagonal;
1153 auto upper_diagonal_values = factorization.
factors.upper_diagonal;
1155 std::vector<blas_int> pivots(order);
1156 for (std::size_t index = 0; index < order; ++index)
1158 if (factorization.
pivot_rows[index] >= order)
1160 throw std::invalid_argument(
"real_general_tridiagonal_solve received an out-of-range row pivot");
1162 pivots[index] = detail::checked_blas_int(factorization.
pivot_rows[index] + 1);
1165 blas_int
const n = detail::checked_blas_int(order);
1166 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
1167 char const trans = detail::lapack_transpose(transpose);
1168 Scalar* lower_diagonal = lower_diagonal_values.empty() ? diagonal_values.data() : lower_diagonal_values.data();
1169 Scalar* upper_diagonal = upper_diagonal_values.empty() ? diagonal_values.data() : upper_diagonal_values.data();
1170 Scalar* second_upper_diagonal =
1171 second_upper_diagonal_values.empty() ? diagonal_values.data() : second_upper_diagonal_values.data();
1172 uni20::lapack::gttrs(trans, n, nrhs, lower_diagonal, diagonal_values.data(), upper_diagonal, second_upper_diagonal,
1173 pivots.data(), right_hand_sides.
data(), n);
1174 return right_hand_sides;
1181template <uni20::LapackReal Scalar>
1184 std::size_t
const order = matrix.
order();
1185 if (matrix.
lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1188 throw std::invalid_argument(
"real_general_tridiagonal_one_norm received inconsistent tridiagonal storage");
1192 for (std::size_t col = 0; col < order; ++col)
1199 if (col + 1 < order)
1216template <uni20::LapackReal Scalar>
1220 std::size_t
const order = factorization.
factors.order();
1221 if (factorization.
factors.lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1222 factorization.
factors.upper_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1225 throw std::invalid_argument(
1226 "real_general_tridiagonal_one_norm_reciprocal_condition_number received inconsistent factors");
1228 if (factorization.
pivot_rows.size() != order)
1230 throw std::invalid_argument(
1231 "real_general_tridiagonal_one_norm_reciprocal_condition_number received inconsistent pivots");
1233 if (original_one_norm <
Scalar{})
1235 throw std::invalid_argument(
1236 "real_general_tridiagonal_one_norm_reciprocal_condition_number requires a nonnegative norm");
1243 auto lower_diagonal_values = factorization.
factors.lower_diagonal;
1244 auto diagonal_values = factorization.
factors.diagonal;
1245 auto upper_diagonal_values = factorization.
factors.upper_diagonal;
1247 std::vector<blas_int> pivots(order);
1248 for (std::size_t index = 0; index < order; ++index)
1250 if (factorization.
pivot_rows[index] >= order)
1252 throw std::invalid_argument(
1253 "real_general_tridiagonal_one_norm_reciprocal_condition_number received an out-of-range pivot");
1255 pivots[index] = detail::checked_blas_int(factorization.
pivot_rows[index] + 1);
1258 blas_int
const n = detail::checked_blas_int(order);
1259 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * n)),
Scalar{});
1260 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
1261 Scalar* lower_diagonal = lower_diagonal_values.empty() ? diagonal_values.data() : lower_diagonal_values.data();
1262 Scalar* upper_diagonal = upper_diagonal_values.empty() ? diagonal_values.data() : upper_diagonal_values.data();
1263 Scalar* second_upper_diagonal =
1264 second_upper_diagonal_values.empty() ? diagonal_values.data() : second_upper_diagonal_values.data();
1265 return uni20::lapack::gtcon(
'1', n, lower_diagonal, diagonal_values.data(), upper_diagonal, second_upper_diagonal,
1266 pivots.data(), original_one_norm, work.data(), iwork.data());
1273template <uni20::LapackReal Scalar>
1289template <uni20::LapackReal Scalar>
1290RealRefinedLinearSolve<Scalar>
1295 std::size_t
const order = coefficients.
order();
1296 if (coefficients.
lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1297 coefficients.
upper_diagonal.size() != (order == 0 ? 0 : order - 1))
1299 throw std::invalid_argument(
"real_general_tridiagonal_refined_solve received inconsistent tridiagonal storage");
1301 if (!std::cmp_equal(right_hand_sides.
rows(), order))
1303 throw std::invalid_argument(
"real_general_tridiagonal_refined_solve received incompatible right-hand sides");
1306 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
1308 result.
solution = right_hand_sides;
1311 if (order == 0 || rhs_count == 0)
1319 std::vector<blas_int> pivots(order);
1320 for (std::size_t index = 0; index < order; ++index)
1322 if (factorization.pivot_rows[index] >= order)
1324 throw std::invalid_argument(
"real_general_tridiagonal_refined_solve received an out-of-range row pivot");
1326 pivots[index] = detail::checked_blas_int(factorization.pivot_rows[index] + 1);
1329 blas_int
const n = detail::checked_blas_int(order);
1330 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
1331 char const trans = detail::lapack_transpose(transpose);
1332 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * n)),
Scalar{});
1333 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
1338 Scalar* factor_lower_diagonal = factorization.factors.lower_diagonal.empty()
1339 ? factorization.factors.diagonal.data()
1340 : factorization.factors.lower_diagonal.data();
1341 Scalar* factor_upper_diagonal = factorization.factors.upper_diagonal.empty()
1342 ? factorization.factors.diagonal.data()
1343 : factorization.factors.upper_diagonal.data();
1344 Scalar* factor_second_upper_diagonal = factorization.second_upper_diagonal.empty()
1345 ? factorization.factors.diagonal.data()
1346 : factorization.second_upper_diagonal.data();
1348 factor_lower_diagonal, factorization.factors.diagonal.data(), factor_upper_diagonal,
1349 factor_second_upper_diagonal, pivots.data(), right_hand_sides.
data(), n, result.
solution.data(),
1366template <uni20::LapackReal Scalar>
1367RealGeneralTridiagonalExpertLinearSolve<Scalar>
1372 std::size_t
const order = coefficients.
order();
1373 if (coefficients.
lower_diagonal.size() != (order == 0 ? 0 : order - 1) ||
1374 coefficients.
upper_diagonal.size() != (order == 0 ? 0 : order - 1))
1376 throw std::invalid_argument(
1377 "real_general_tridiagonal_expert_linear_solve received inconsistent tridiagonal storage");
1379 if (!std::cmp_equal(right_hand_sides.
rows(), order))
1381 throw std::invalid_argument(
"real_general_tridiagonal_expert_linear_solve received incompatible right-hand sides");
1384 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
1388 result.
factorization.factors.lower_diagonal.resize(order == 0 ? 0 : order - 1);
1389 result.
factorization.factors.upper_diagonal.resize(order == 0 ? 0 : order - 1);
1390 result.
factorization.second_upper_diagonal.resize(order > 2 ? order - 2 : 0);
1395 if (order == 0 || rhs_count == 0)
1400 std::vector<blas_int> pivots(order);
1401 blas_int
const n = detail::checked_blas_int(order);
1402 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
1403 char const trans = detail::lapack_transpose(transpose);
1404 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * n)),
Scalar{});
1405 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
1420 'N', trans, n, nrhs, lower_diagonal, coefficients.
diagonal.data(), upper_diagonal, factor_lower_diagonal,
1421 result.
factorization.factors.diagonal.data(), factor_upper_diagonal, factor_second_upper_diagonal, pivots.data(),
1424 for (std::size_t index = 0; index < order; ++index)
1426 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > order)
1428 throw std::runtime_error(
"LAPACK gtsvx returned an invalid row pivot");
1430 result.
factorization.pivot_rows[index] =
static_cast<std::size_t
>(pivots[index] - 1);
1442template <uni20::LapackReal Scalar>
1444 Scalar original_one_norm)
1446 if (!std::cmp_equal(factorization.
factors.storage.cols(), factorization.
factors.order) ||
1447 std::cmp_less(factorization.
factors.storage.rows(),
1448 2 * factorization.
factors.lower_bandwidth + factorization.
factors.upper_bandwidth + 1))
1450 throw std::invalid_argument(
"real_general_band_one_norm_reciprocal_condition_number received inconsistent factors");
1454 throw std::invalid_argument(
"real_general_band_one_norm_reciprocal_condition_number received inconsistent pivots");
1456 if (original_one_norm <
Scalar{})
1458 throw std::invalid_argument(
"real_general_band_one_norm_reciprocal_condition_number requires a nonnegative norm");
1460 if (factorization.
factors.order == 0)
1466 std::vector<blas_int> pivots(factorization.
factors.order);
1467 for (std::size_t index = 0; index < factorization.
factors.order; ++index)
1471 throw std::invalid_argument(
1472 "real_general_band_one_norm_reciprocal_condition_number received an out-of-range pivot");
1474 pivots[index] = detail::checked_blas_int(factorization.
pivot_rows[index] + 1);
1477 blas_int
const n = detail::checked_blas_int(factorization.
factors.order);
1478 blas_int
const kl = detail::checked_blas_int(factorization.
factors.lower_bandwidth);
1479 blas_int
const ku = detail::checked_blas_int(factorization.
factors.upper_bandwidth);
1480 blas_int
const ldab = detail::checked_blas_int(factors.
rows());
1481 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * n)),
Scalar{});
1482 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
1494template <uni20::LapackReal Scalar>
1512template <uni20::LapackReal Scalar>
1517 if (!std::cmp_equal(coefficients.
storage.cols(), coefficients.
order) ||
1520 throw std::invalid_argument(
"real_general_band_refined_solve received inconsistent band storage");
1522 if (!std::cmp_equal(right_hand_sides.
rows(), coefficients.
order))
1524 throw std::invalid_argument(
"real_general_band_refined_solve received incompatible right-hand sides");
1527 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
1529 result.
solution = right_hand_sides;
1532 if (coefficients.
order == 0 || rhs_count == 0)
1538 std::vector<blas_int> pivots(factorization.factors.order);
1539 for (std::size_t index = 0; index < factorization.factors.order; ++index)
1541 if (factorization.pivot_rows[index] >= factorization.factors.order)
1543 throw std::invalid_argument(
"real_general_band_refined_solve received an out-of-range row pivot");
1545 pivots[index] = detail::checked_blas_int(factorization.pivot_rows[index] + 1);
1548 blas_int
const n = detail::checked_blas_int(coefficients.
order);
1549 blas_int
const kl = detail::checked_blas_int(coefficients.
lower_bandwidth);
1550 blas_int
const ku = detail::checked_blas_int(coefficients.
upper_bandwidth);
1551 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
1552 blas_int
const ldab = detail::checked_blas_int(coefficients.
storage.rows());
1553 blas_int
const ldafb = detail::checked_blas_int(factorization.factors.storage.rows());
1554 char const trans = detail::lapack_transpose(transpose);
1556 uni20::lapack::gbtrs(trans, n, kl, ku, nrhs, factorization.factors.storage.data(), ldafb, pivots.data(),
1559 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * n)),
Scalar{});
1560 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
1562 uni20::lapack::gbrfs(trans, n, kl, ku, nrhs, compact_band, ldab, factorization.factors.storage.data(), ldafb,
1563 pivots.data(), right_hand_sides.
data(), n, result.
solution.data(), n,
1580template <uni20::LapackReal Scalar>
1581RealGeneralBandExpertLinearSolve<Scalar>
1586 if (!std::cmp_equal(coefficients.
storage.cols(), coefficients.
order) ||
1589 throw std::invalid_argument(
"real_general_band_expert_linear_solve received inconsistent band storage");
1591 if (!std::cmp_equal(right_hand_sides.
rows(), coefficients.
order))
1593 throw std::invalid_argument(
"real_general_band_expert_linear_solve received incompatible right-hand sides");
1596 std::size_t
const n = coefficients.
order;
1597 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
1609 if (n == 0 || rhs_count == 0)
1614 blas_int
const order = detail::checked_blas_int(n);
1615 blas_int
const kl = detail::checked_blas_int(coefficients.
lower_bandwidth);
1616 blas_int
const ku = detail::checked_blas_int(coefficients.
upper_bandwidth);
1617 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
1618 blas_int
const ldab = detail::checked_blas_int(coefficients.
storage.rows());
1619 blas_int
const ldafb = detail::checked_blas_int(result.
factors.storage.rows());
1620 std::vector<blas_int> pivots(n, 0);
1621 std::vector<Scalar> row_scale(n,
Scalar{});
1622 std::vector<Scalar> column_scale(n,
Scalar{});
1623 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
1624 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
1625 char const trans = detail::lapack_transpose(transpose);
1631 'N', trans, order, kl, ku, nrhs, compact_band, ldab, result.
factors.storage.data(), ldafb, pivots.data(), equed,
1632 row_scale.data(), column_scale.data(), right_hand_sides.
data(), order, result.
solution.data(), order, rcond,
1636 for (std::size_t index = 0; index < n; ++index)
1638 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > n)
1640 throw std::runtime_error(
"LAPACK gbsvx returned an invalid row pivot");
1642 result.
pivot_rows[index] =
static_cast<std::size_t
>(pivots[index] - 1);
1656template <uni20::LapackReal Scalar>
1659 if (!std::cmp_equal(band_matrix.
storage.cols(), band_matrix.
order) ||
1662 throw std::invalid_argument(
"real_general_band_equilibration received inconsistent band storage");
1668 if (band_matrix.
order == 0)
1673 blas_int
const n = detail::checked_blas_int(band_matrix.
order);
1674 blas_int
const kl = detail::checked_blas_int(band_matrix.
lower_bandwidth);
1675 blas_int
const ku = detail::checked_blas_int(band_matrix.
upper_bandwidth);
1676 blas_int
const ldab = detail::checked_blas_int(band_matrix.
storage.rows());
1690template <uni20::LapackReal Scalar>
1693 if (!std::cmp_equal(band_matrix.
storage.cols(), band_matrix.
order) ||
1696 throw std::invalid_argument(
"real_general_band_power_of_two_equilibration received inconsistent band storage");
1702 if (band_matrix.
order == 0)
1707 blas_int
const n = detail::checked_blas_int(band_matrix.
order);
1708 blas_int
const kl = detail::checked_blas_int(band_matrix.
lower_bandwidth);
1709 blas_int
const ku = detail::checked_blas_int(band_matrix.
upper_bandwidth);
1710 blas_int
const ldab = detail::checked_blas_int(band_matrix.
storage.rows());
1724template <uni20::LapackReal Scalar>
1730 if (matrix.
rows() == 0 || matrix.
cols() == 0)
1735 blas_int
const rows = detail::checked_blas_int(matrix.
rows());
1736 blas_int
const cols = detail::checked_blas_int(matrix.
cols());
1749template <uni20::LapackReal Scalar>
1750RealSymmetricPositiveDefiniteEquilibration<Scalar>
1753 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
1755 throw std::invalid_argument(
"real_symmetric_positive_definite_equilibration requires a square matrix");
1760 if (matrix.
rows() == 0)
1765 blas_int
const order = detail::checked_blas_int(matrix.
rows());
1777template <uni20::LapackReal Scalar>
1778RealSymmetricPositiveDefiniteFactorization<Scalar>
1782 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
1784 throw std::invalid_argument(
"real_symmetric_positive_definite_factorization requires a square matrix");
1788 result.
factors = std::move(matrix);
1790 if (result.
factors.rows() == 0)
1795 blas_int
const order = detail::checked_blas_int(result.
factors.rows());
1796 char const uplo = detail::lapack_uplo(triangle);
1810template <uni20::LapackReal Scalar>
1811RealSymmetricPositiveDefiniteBandMatrix<Scalar>
1813 std::size_t bandwidth,
MatrixFill triangle = MatrixFill::Upper)
1815 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
1817 throw std::invalid_argument(
"real_symmetric_positive_definite_band_from_dense requires a square matrix");
1819 if (triangle != MatrixFill::Upper && triangle != MatrixFill::Lower)
1821 throw std::invalid_argument(
"real_symmetric_positive_definite_band_from_dense requires upper or lower storage");
1824 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
1831 for (std::size_t col = 0; col < n; ++col)
1833 if (triangle == MatrixFill::Upper)
1835 std::size_t
const first_row = col > bandwidth ? col - bandwidth : 0;
1836 for (std::size_t
row = first_row;
row <= col; ++
row)
1838 result.
storage[bandwidth +
row - col, col] = matrix[
row, col];
1843 std::size_t
const last_row = std::min(n - 1, col + bandwidth);
1844 for (std::size_t
row = col;
row <= last_row; ++
row)
1861template <uni20::LapackReal Scalar>
1862detail::ColumnMajorLapackMatrix<Scalar>
1866 if (!std::cmp_equal(coefficients.
storage.cols(), coefficients.
order) ||
1869 throw std::invalid_argument(
"real_symmetric_positive_definite_band_solve received inconsistent band storage");
1871 if (!std::cmp_equal(right_hand_sides.
rows(), coefficients.
order))
1873 throw std::invalid_argument(
"real_symmetric_positive_definite_band_solve received incompatible right-hand sides");
1875 if (coefficients.
order == 0 || right_hand_sides.
cols() == 0)
1877 return right_hand_sides;
1880 blas_int
const n = detail::checked_blas_int(coefficients.
order);
1881 blas_int
const kd = detail::checked_blas_int(coefficients.
bandwidth);
1882 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
1883 blas_int
const ldab = detail::checked_blas_int(coefficients.
storage.rows());
1884 char const uplo = detail::lapack_uplo(coefficients.
triangle);
1886 return right_hand_sides;
1893template <uni20::LapackReal Scalar>
1894RealSymmetricPositiveDefiniteBandFactorization<Scalar>
1897 if (!std::cmp_equal(matrix.
storage.cols(), matrix.
order) ||
1900 throw std::invalid_argument(
1901 "real_symmetric_positive_definite_band_factorization received inconsistent band storage");
1903 if (matrix.
triangle != MatrixFill::Upper && matrix.
triangle != MatrixFill::Lower)
1905 throw std::invalid_argument(
"real_symmetric_positive_definite_band_factorization requires upper or lower storage");
1909 result.
factors = std::move(matrix);
1910 if (result.
factors.order == 0)
1915 blas_int
const n = detail::checked_blas_int(result.
factors.order);
1916 blas_int
const kd = detail::checked_blas_int(result.
factors.bandwidth);
1917 blas_int
const ldab = detail::checked_blas_int(result.
factors.storage.rows());
1918 char const uplo = detail::lapack_uplo(result.
factors.triangle);
1928template <uni20::LapackReal Scalar>
1929detail::ColumnMajorLapackMatrix<Scalar>
1933 if (!std::cmp_equal(factorization.
factors.storage.cols(), factorization.
factors.order) ||
1934 std::cmp_less(factorization.
factors.storage.rows(), factorization.
factors.bandwidth + 1))
1936 throw std::invalid_argument(
"real_symmetric_positive_definite_band_solve received inconsistent band factors");
1938 if (!std::cmp_equal(right_hand_sides.
rows(), factorization.
factors.order))
1940 throw std::invalid_argument(
"real_symmetric_positive_definite_band_solve received incompatible right-hand sides");
1942 if (factorization.
factors.order == 0 || right_hand_sides.
cols() == 0)
1944 return right_hand_sides;
1948 blas_int
const n = detail::checked_blas_int(factorization.
factors.order);
1949 blas_int
const kd = detail::checked_blas_int(factorization.
factors.bandwidth);
1950 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
1951 blas_int
const ldab = detail::checked_blas_int(factors.
rows());
1952 char const uplo = detail::lapack_uplo(factorization.
factors.triangle);
1954 return right_hand_sides;
1961template <uni20::LapackReal Scalar>
1964 if (!std::cmp_equal(matrix.
storage.cols(), matrix.
order) ||
1967 throw std::invalid_argument(
"real_symmetric_positive_definite_band_one_norm received inconsistent band storage");
1969 if (matrix.
triangle != MatrixFill::Upper && matrix.
triangle != MatrixFill::Lower)
1971 throw std::invalid_argument(
"real_symmetric_positive_definite_band_one_norm requires upper or lower storage");
1974 std::vector<Scalar> column_sums(matrix.
order,
Scalar{});
1975 for (std::size_t col = 0; col < matrix.
order; ++col)
1977 if (matrix.
triangle == MatrixFill::Upper)
1980 for (std::size_t
row = first_row;
row <= col; ++
row)
1983 column_sums[col] += magnitude;
1986 column_sums[
row] += magnitude;
1992 std::size_t
const last_row = std::min(matrix.
order - 1, col + matrix.
bandwidth);
1993 for (std::size_t
row = col;
row <= last_row; ++
row)
1996 column_sums[col] += magnitude;
1999 column_sums[
row] += magnitude;
2021template <uni20::LapackReal Scalar>
2025 if (!std::cmp_equal(factorization.
factors.storage.cols(), factorization.
factors.order) ||
2026 std::cmp_less(factorization.
factors.storage.rows(), factorization.
factors.bandwidth + 1))
2028 throw std::invalid_argument(
2029 "real_symmetric_positive_definite_band_one_norm_reciprocal_condition_number received inconsistent factors");
2031 if (factorization.
factors.triangle != MatrixFill::Upper && factorization.
factors.triangle != MatrixFill::Lower)
2033 throw std::invalid_argument(
2034 "real_symmetric_positive_definite_band_one_norm_reciprocal_condition_number requires upper or lower storage");
2036 if (original_one_norm <
Scalar{})
2038 throw std::invalid_argument(
2039 "real_symmetric_positive_definite_band_one_norm_reciprocal_condition_number requires a nonnegative norm");
2041 if (factorization.
factors.order == 0)
2047 blas_int
const n = detail::checked_blas_int(factorization.
factors.order);
2048 blas_int
const kd = detail::checked_blas_int(factorization.
factors.bandwidth);
2049 blas_int
const ldab = detail::checked_blas_int(factors.
rows());
2050 char const uplo = detail::lapack_uplo(factorization.
factors.triangle);
2051 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * n)),
Scalar{});
2052 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
2063template <uni20::LapackReal Scalar>
2080template <uni20::LapackReal Scalar>
2081RealRefinedLinearSolve<Scalar>
2085 if (!std::cmp_equal(coefficients.
storage.cols(), coefficients.
order) ||
2088 throw std::invalid_argument(
2089 "real_symmetric_positive_definite_band_refined_solve received inconsistent band storage");
2091 if (!std::cmp_equal(right_hand_sides.
rows(), coefficients.
order))
2093 throw std::invalid_argument(
2094 "real_symmetric_positive_definite_band_refined_solve received incompatible right-hand sides");
2097 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2099 result.
solution = right_hand_sides;
2102 if (coefficients.
order == 0 || rhs_count == 0)
2110 blas_int
const n = detail::checked_blas_int(coefficients.
order);
2111 blas_int
const kd = detail::checked_blas_int(coefficients.
bandwidth);
2112 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2113 blas_int
const ldab = detail::checked_blas_int(coefficients.
storage.rows());
2114 blas_int
const ldafb = detail::checked_blas_int(factorization.factors.storage.rows());
2115 char const uplo = detail::lapack_uplo(coefficients.
triangle);
2116 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * n)),
Scalar{});
2117 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, n)), 0);
2136template <uni20::LapackReal Scalar>
2137RealSymmetricPositiveDefiniteBandExpertLinearSolve<Scalar>
2141 if (!std::cmp_equal(coefficients.
storage.cols(), coefficients.
order) ||
2144 throw std::invalid_argument(
2145 "real_symmetric_positive_definite_band_expert_linear_solve received inconsistent band storage");
2147 if (!std::cmp_equal(right_hand_sides.
rows(), coefficients.
order))
2149 throw std::invalid_argument(
2150 "real_symmetric_positive_definite_band_expert_linear_solve received incompatible right-hand sides");
2153 std::size_t
const n = coefficients.
order;
2154 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2165 if (n == 0 || rhs_count == 0)
2170 blas_int
const order = detail::checked_blas_int(n);
2171 blas_int
const kd = detail::checked_blas_int(coefficients.
bandwidth);
2172 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2173 blas_int
const ldab = detail::checked_blas_int(coefficients.
storage.rows());
2174 blas_int
const ldafb = detail::checked_blas_int(result.
factorization.factors.storage.rows());
2175 char const uplo = detail::lapack_uplo(coefficients.
triangle);
2178 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
2179 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
2182 'N', uplo, order, kd, nrhs, coefficients.
storage.data(), ldab, result.
factorization.factors.storage.data(), ldafb,
2183 equed, result.
scale.data(), right_hand_sides.
data(), order, result.
solution.data(), order, rcond,
2196template <uni20::LapackReal Scalar>
2197RealSymmetricPositiveDefiniteTridiagonalMatrix<Scalar>
2200 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
2202 throw std::invalid_argument(
"real_symmetric_positive_definite_tridiagonal_from_dense requires a square matrix");
2207 if (matrix.
rows() > 0)
2213 result.
diagonal[index] = matrix[index, index];
2214 if (index + 1 < matrix.
rows())
2216 result.
offdiagonal[index] = matrix[index + 1, index];
2228template <uni20::LapackReal Scalar>
2229detail::ColumnMajorLapackMatrix<Scalar>
2233 std::size_t
const order = coefficients.
order();
2234 if (coefficients.
offdiagonal.size() != (order == 0 ? 0 : order - 1))
2236 throw std::invalid_argument(
2237 "real_symmetric_positive_definite_tridiagonal_solve received inconsistent tridiagonal storage");
2239 if (!std::cmp_equal(right_hand_sides.
rows(), order))
2241 throw std::invalid_argument(
2242 "real_symmetric_positive_definite_tridiagonal_solve received incompatible right-hand sides");
2244 if (order == 0 || right_hand_sides.
cols() == 0)
2246 return right_hand_sides;
2249 blas_int
const n = detail::checked_blas_int(order);
2250 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
2254 return right_hand_sides;
2261template <uni20::LapackReal Scalar>
2262RealSymmetricPositiveDefiniteTridiagonalFactorization<Scalar>
2266 std::size_t
const order = matrix.
order();
2267 if (matrix.
offdiagonal.size() != (order == 0 ? 0 : order - 1))
2269 throw std::invalid_argument(
2270 "real_symmetric_positive_definite_tridiagonal_factorization received inconsistent tridiagonal storage");
2274 result.
factors = std::move(matrix);
2280 blas_int
const n = detail::checked_blas_int(order);
2282 result.
factors.offdiagonal.empty() ? result.
factors.diagonal.data() : result.
factors.offdiagonal.data();
2292template <uni20::LapackReal Scalar>
2297 std::size_t
const order = factorization.
factors.order();
2298 if (factorization.
factors.offdiagonal.size() != (order == 0 ? 0 : order - 1))
2300 throw std::invalid_argument(
2301 "real_symmetric_positive_definite_tridiagonal_solve received inconsistent tridiagonal factors");
2303 if (!std::cmp_equal(right_hand_sides.
rows(), order))
2305 throw std::invalid_argument(
2306 "real_symmetric_positive_definite_tridiagonal_solve received incompatible right-hand sides");
2308 if (order == 0 || right_hand_sides.
cols() == 0)
2310 return right_hand_sides;
2313 std::vector<Scalar> diagonal = factorization.
factors.diagonal;
2314 std::vector<Scalar> offdiagonal = factorization.
factors.offdiagonal;
2315 blas_int
const n = detail::checked_blas_int(order);
2316 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
2317 Scalar* offdiagonal_data = offdiagonal.empty() ? diagonal.data() : offdiagonal.data();
2319 return right_hand_sides;
2326template <uni20::LapackReal Scalar>
2330 std::size_t
const order = matrix.
order();
2331 if (matrix.
offdiagonal.size() != (order == 0 ? 0 : order - 1))
2333 throw std::invalid_argument(
2334 "real_symmetric_positive_definite_tridiagonal_one_norm received inconsistent tridiagonal storage");
2338 for (std::size_t col = 0; col < order; ++col)
2345 if (col + 1 < order)
2362template <uni20::LapackReal Scalar>
2366 std::size_t
const order = factorization.
factors.order();
2367 if (factorization.
factors.offdiagonal.size() != (order == 0 ? 0 : order - 1))
2369 throw std::invalid_argument(
2370 "real_symmetric_positive_definite_tridiagonal_one_norm_reciprocal_condition_number received inconsistent "
2373 if (original_one_norm <
Scalar{})
2375 throw std::invalid_argument(
"real_symmetric_positive_definite_tridiagonal_one_norm_reciprocal_condition_number "
2376 "requires a nonnegative norm");
2383 std::vector<Scalar> diagonal = factorization.
factors.diagonal;
2384 std::vector<Scalar> offdiagonal = factorization.
factors.offdiagonal;
2385 blas_int
const n = detail::checked_blas_int(order);
2386 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, n)),
Scalar{});
2387 Scalar* offdiagonal_data = offdiagonal.empty() ? diagonal.data() : offdiagonal.data();
2388 return uni20::lapack::ptcon(n, diagonal.data(), offdiagonal_data, original_one_norm, work.data());
2395template <uni20::LapackReal Scalar>
2411template <uni20::LapackReal Scalar>
2416 std::size_t
const order = coefficients.
order();
2417 if (coefficients.
offdiagonal.size() != (order == 0 ? 0 : order - 1))
2419 throw std::invalid_argument(
2420 "real_symmetric_positive_definite_tridiagonal_refined_solve received inconsistent tridiagonal storage");
2422 if (!std::cmp_equal(right_hand_sides.
rows(), order))
2424 throw std::invalid_argument(
2425 "real_symmetric_positive_definite_tridiagonal_refined_solve received incompatible right-hand sides");
2428 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2430 result.
solution = right_hand_sides;
2433 if (order == 0 || rhs_count == 0)
2441 blas_int
const n = detail::checked_blas_int(order);
2442 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2443 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * n)),
Scalar{});
2446 Scalar* factor_offdiagonal = factorization.factors.offdiagonal.empty() ? factorization.factors.diagonal.data()
2447 : factorization.factors.offdiagonal.data();
2449 factor_offdiagonal, right_hand_sides.
data(), n, result.
solution.data(), n,
2464template <uni20::LapackReal Scalar>
2465RealSymmetricPositiveDefiniteTridiagonalExpertLinearSolve<Scalar>
2470 std::size_t
const order = coefficients.
order();
2471 if (coefficients.
offdiagonal.size() != (order == 0 ? 0 : order - 1))
2473 throw std::invalid_argument(
2474 "real_symmetric_positive_definite_tridiagonal_expert_linear_solve received inconsistent tridiagonal storage");
2476 if (!std::cmp_equal(right_hand_sides.
rows(), order))
2478 throw std::invalid_argument(
2479 "real_symmetric_positive_definite_tridiagonal_expert_linear_solve received incompatible right-hand sides");
2482 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2486 result.
factorization.factors.offdiagonal.resize(order == 0 ? 0 : order - 1);
2489 if (order == 0 || rhs_count == 0)
2494 blas_int
const n = detail::checked_blas_int(order);
2495 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2496 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * n)),
Scalar{});
2503 'N', n, nrhs, coefficients.
diagonal.data(), offdiagonal, result.
factorization.factors.diagonal.data(),
2521template <uni20::LapackReal Scalar>
2522RealPivotedCholeskyFactorization<Scalar>
2526 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
2528 throw std::invalid_argument(
"real_pivoted_cholesky_factorization requires a square matrix");
2531 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
2532 RealPivotedCholeskyFactorization<Scalar> result;
2533 result.factors = std::move(matrix);
2534 result.pivot_order.resize(n);
2535 std::iota(result.pivot_order.begin(), result.pivot_order.end(), std::size_t{0});
2536 result.triangle = triangle;
2543 blas_int
const order = detail::checked_blas_int(n);
2544 char const uplo = detail::lapack_uplo(triangle);
2545 std::vector<blas_int> pivots(n, 0);
2546 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order)), Scalar{});
2548 result.rank_deficient =
2549 uni20::lapack::pstrf(uplo, order, result.factors.data(), order, pivots.data(), rank, tolerance, work.data());
2550 if (rank < 0 || rank > order)
2552 throw std::runtime_error(
"LAPACK pstrf returned an invalid numerical rank");
2554 result.rank =
static_cast<std::size_t
>(rank);
2555 for (std::size_t index = 0; index < n; ++index)
2557 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > n)
2559 throw std::runtime_error(
"LAPACK pstrf returned an invalid pivot order");
2561 result.pivot_order[index] =
static_cast<std::size_t
>(pivots[index] - 1);
2574template <uni20::LapackReal Scalar>
2575detail::ColumnMajorLapackMatrix<Scalar>
2579 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
2581 throw std::invalid_argument(
"real_dense_solve_linear_system requires a square coefficient matrix");
2583 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
2585 throw std::invalid_argument(
"real_dense_solve_linear_system received incompatible right-hand sides");
2588 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
2591 return right_hand_sides;
2594 blas_int
const order = detail::checked_blas_int(n);
2595 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
2596 std::vector<blas_int> pivots(n);
2598 return right_hand_sides;
2612template <uni20::LapackReal Scalar>
2616 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
2618 throw std::invalid_argument(
"real_expert_linear_solve requires a square coefficient matrix");
2620 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
2622 throw std::invalid_argument(
"real_expert_linear_solve received incompatible right-hand sides");
2625 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
2626 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2634 if (n == 0 || rhs_count == 0)
2639 blas_int
const order = detail::checked_blas_int(n);
2640 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2641 std::vector<blas_int> pivots(n, 0);
2642 std::vector<Scalar> row_scale(n,
Scalar{});
2643 std::vector<Scalar> column_scale(n,
Scalar{});
2644 std::vector<Scalar> work(
static_cast<std::size_t
>(4 * order),
Scalar{});
2645 std::vector<blas_int> iwork(n, 0);
2650 'N',
'N', order, nrhs, coefficients.
data(), order, result.
factors.data(), order, pivots.data(), equed,
2651 row_scale.data(), column_scale.data(), right_hand_sides.
data(), order, result.
solution.data(), order, rcond,
2655 for (std::size_t index = 0; index < n; ++index)
2657 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > n)
2659 throw std::runtime_error(
"LAPACK gesvx returned an invalid row pivot");
2661 result.
pivot_rows[index] =
static_cast<std::size_t
>(pivots[index] - 1);
2672template <uni20::LapackReal Scalar>
2675 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
2677 throw std::invalid_argument(
"real_lu_factorization requires a square matrix");
2680 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
2682 result.
factors = std::move(matrix);
2690 blas_int
const order = detail::checked_blas_int(n);
2691 std::vector<blas_int> pivots(n);
2693 for (std::size_t index = 0; index < n; ++index)
2695 if (pivots[index] <= 0 ||
static_cast<std::size_t
>(pivots[index]) > n)
2697 throw std::runtime_error(
"LAPACK getrf returned an invalid row pivot");
2699 result.
pivot_rows[index] =
static_cast<std::size_t
>(pivots[index] - 1);
2712template <uni20::LapackReal Scalar>
2717 if (!std::cmp_equal(factorization.
factors.rows(), factorization.
factors.cols()))
2719 throw std::invalid_argument(
"real_lu_solve requires square LU factors");
2721 std::size_t
const n =
static_cast<std::size_t
>(factorization.
factors.rows());
2724 throw std::invalid_argument(
"real_lu_solve received inconsistent pivot metadata");
2726 if (!std::cmp_equal(right_hand_sides.
rows(), n))
2728 throw std::invalid_argument(
"real_lu_solve received incompatible right-hand sides");
2730 if (n == 0 || right_hand_sides.
cols() == 0)
2732 return right_hand_sides;
2736 std::vector<blas_int> pivots(n);
2737 for (std::size_t index = 0; index < n; ++index)
2741 throw std::invalid_argument(
"real_lu_solve received an out-of-range row pivot");
2743 pivots[index] = detail::checked_blas_int(factorization.
pivot_rows[index] + 1);
2746 blas_int
const order = detail::checked_blas_int(n);
2747 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
2748 char const trans = detail::lapack_transpose(transpose);
2750 return right_hand_sides;
2763template <uni20::LapackReal Scalar>
2768 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
2770 throw std::invalid_argument(
"real_refined_linear_solve requires a square coefficient matrix");
2772 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
2774 throw std::invalid_argument(
"real_refined_linear_solve received incompatible right-hand sides");
2777 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
2778 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2780 result.
solution = right_hand_sides;
2783 if (n == 0 || rhs_count == 0)
2789 blas_int
const order = detail::checked_blas_int(n);
2790 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2791 std::vector<blas_int> pivots(n);
2794 char const trans = detail::lapack_transpose(transpose);
2797 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
2798 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
2800 right_hand_sides.
data(), order, result.
solution.data(), order,
2813template <uni20::LapackReal Scalar>
2815 Scalar original_one_norm)
2817 if (!std::cmp_equal(factorization.
factors.rows(), factorization.
factors.cols()))
2819 throw std::invalid_argument(
"real_lu_one_norm_reciprocal_condition_number requires square LU factors");
2821 if (original_one_norm <
Scalar{})
2823 throw std::invalid_argument(
"real_lu_one_norm_reciprocal_condition_number requires a nonnegative matrix norm");
2826 std::size_t
const n =
static_cast<std::size_t
>(factorization.
factors.rows());
2833 blas_int
const order = detail::checked_blas_int(n);
2834 std::vector<Scalar> work(
static_cast<std::size_t
>(4 * order),
Scalar{});
2835 std::vector<blas_int> iwork(n);
2845template <uni20::LapackReal Scalar>
2865template <uni20::LapackReal Scalar>
2866detail::ColumnMajorLapackMatrix<Scalar>
2871 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
2873 throw std::invalid_argument(
"real_triangular_solve requires a square coefficient matrix");
2875 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
2877 throw std::invalid_argument(
"real_triangular_solve received incompatible right-hand sides");
2880 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
2881 if (n == 0 || right_hand_sides.
cols() == 0)
2883 return right_hand_sides;
2886 blas_int
const order = detail::checked_blas_int(n);
2887 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
2888 char const uplo = detail::lapack_uplo(triangle);
2889 char const trans = detail::lapack_transpose(transpose);
2890 char const diag = unit_diagonal ?
'U' :
'N';
2892 return right_hand_sides;
2906template <uni20::LapackReal Scalar>
2911 bool unit_diagonal =
false)
2913 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
2915 throw std::invalid_argument(
"real_triangular_refined_solve requires a square coefficient matrix");
2917 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
2919 throw std::invalid_argument(
"real_triangular_refined_solve received incompatible right-hand sides");
2922 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
2923 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
2925 result.
solution = right_hand_sides;
2928 if (n == 0 || rhs_count == 0)
2933 blas_int
const order = detail::checked_blas_int(n);
2934 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
2935 char const uplo = detail::lapack_uplo(triangle);
2936 char const trans = detail::lapack_transpose(transpose);
2937 char const diag = unit_diagonal ?
'U' :
'N';
2940 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
2941 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
2957template <uni20::LapackReal Scalar>
2960 bool unit_diagonal =
false)
2962 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
2964 throw std::invalid_argument(
"real_triangular_inverse requires a square matrix");
2967 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
2973 blas_int
const order = detail::checked_blas_int(n);
2974 char const uplo = detail::lapack_uplo(triangle);
2975 char const diag = unit_diagonal ?
'U' :
'N';
2978 for (std::size_t
row = 0;
row < n; ++
row)
2980 for (std::size_t col = 0; col < n; ++col)
2982 bool const selected = triangle == MatrixFill::Upper ? row <= col : row >= col;
3005template <uni20::LapackReal Scalar>
3008 bool unit_diagonal =
false)
3010 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
3012 throw std::invalid_argument(
"real_triangular_one_norm_reciprocal_condition_number requires a square matrix");
3015 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
3021 blas_int
const order = detail::checked_blas_int(n);
3022 char const uplo = detail::lapack_uplo(triangle);
3023 char const diag = unit_diagonal ?
'U' :
'N';
3024 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
3025 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3044template <uni20::LapackReal Scalar>
3051 if (!std::cmp_equal(left.rows(), left.cols()))
3053 throw std::invalid_argument(
"real_sylvester_solve requires a square left matrix");
3055 if (!std::cmp_equal(right.rows(), right.cols()))
3057 throw std::invalid_argument(
"real_sylvester_solve requires a square right matrix");
3059 if (!std::cmp_equal(rhs.
rows(), left.rows()) || !std::cmp_equal(rhs.
cols(), right.rows()))
3061 throw std::invalid_argument(
"real_sylvester_solve received incompatible right-hand side dimensions");
3063 if (sign != 1 && sign != -1)
3065 throw std::invalid_argument(
"real_sylvester_solve sign must be +1 or -1");
3070 if (left.rows() == 0 || right.rows() == 0)
3075 blas_int
const m = detail::checked_blas_int(left.rows());
3076 blas_int
const n = detail::checked_blas_int(right.rows());
3077 char const trans_a = detail::lapack_transpose(transpose_left);
3078 char const trans_b = detail::lapack_transpose(transpose_right);
3092template <uni20::LapackReal Scalar>
3095 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
3097 throw std::invalid_argument(
"real_dense_inverse requires a square matrix");
3100 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
3106 blas_int
const order = detail::checked_blas_int(n);
3107 std::vector<blas_int> pivots(n);
3111 blas_int
const query_lwork = -1;
3114 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3115 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
3129template <uni20::LapackReal Scalar>
3133 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3135 throw std::invalid_argument(
"real_least_squares received incompatible right-hand sides");
3138 std::size_t
const rows =
static_cast<std::size_t
>(coefficients.
rows());
3139 std::size_t
const cols =
static_cast<std::size_t
>(coefficients.
cols());
3140 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3142 if (cols == 0 || rhs_count == 0)
3152 std::size_t
const workspace_rows = std::max(rows, cols);
3154 for (std::size_t
row = 0;
row < rows; ++
row)
3156 for (std::size_t col = 0; col < rhs_count; ++col)
3158 rhs_workspace[
row, col] = right_hand_sides[
row, col];
3162 blas_int
const m = detail::checked_blas_int(rows);
3163 blas_int
const n = detail::checked_blas_int(cols);
3164 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3165 blas_int
const lda = std::max<blas_int>(1, m);
3166 blas_int
const ldb = detail::checked_blas_int(workspace_rows);
3167 char const trans =
'N';
3170 blas_int
const query_lwork = -1;
3173 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3174 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
3177 for (std::size_t
row = 0;
row < cols; ++
row)
3179 for (std::size_t col = 0; col < rhs_count; ++col)
3181 solution[
row, col] = rhs_workspace[
row, col];
3196template <uni20::LapackReal Scalar>
3202 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3204 throw std::invalid_argument(
"real_svd_least_squares received incompatible right-hand sides");
3207 std::size_t
const rows =
static_cast<std::size_t
>(coefficients.
rows());
3208 std::size_t
const cols =
static_cast<std::size_t
>(coefficients.
cols());
3209 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3210 RealSvdLeastSquares<Scalar> result;
3211 result.solution = detail::ColumnMajorLapackMatrix<Scalar>(cols, rhs_count);
3212 result.singular_values.resize(std::min(rows, cols));
3213 if (cols == 0 || rhs_count == 0)
3219 std::fill_n(result.solution.data(), result.solution.size(), Scalar{});
3223 std::size_t
const workspace_rows = std::max(rows, cols);
3224 detail::ColumnMajorLapackMatrix<Scalar> rhs_workspace(workspace_rows, rhs_count);
3227 for (std::size_t col = 0; col < rhs_count; ++col)
3229 rhs_workspace[
row, col] = right_hand_sides[
row, col];
3233 blas_int
const m = detail::checked_blas_int(rows);
3234 blas_int
const n = detail::checked_blas_int(cols);
3235 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3236 blas_int
const lda = std::max<blas_int>(1, m);
3237 blas_int
const ldb = detail::checked_blas_int(workspace_rows);
3240 Scalar work_query{};
3241 blas_int
const query_lwork = -1;
3242 uni20::lapack::gelss(m, n, nrhs, coefficients.
data(), lda, rhs_workspace.data(), ldb, result.singular_values.data(),
3243 rcond, rank, &work_query, query_lwork);
3245 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3246 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork), Scalar{});
3247 uni20::lapack::gelss(m, n, nrhs, coefficients.
data(), lda, rhs_workspace.data(), ldb, result.singular_values.data(),
3248 rcond, rank, work.data(), lwork);
3252 throw std::runtime_error(
"LAPACK gelss returned a negative rank");
3254 result.rank =
static_cast<std::size_t
>(rank);
3255 for (std::size_t
row = 0;
row < cols; ++
row)
3257 for (std::size_t col = 0; col < rhs_count; ++col)
3259 result.solution[
row, col] = rhs_workspace[
row, col];
3275template <uni20::LapackReal Scalar>
3276RealSvdLeastSquares<Scalar>
3281 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3283 throw std::invalid_argument(
"real_divide_and_conquer_svd_least_squares received incompatible right-hand sides");
3286 std::size_t
const rows =
static_cast<std::size_t
>(coefficients.
rows());
3287 std::size_t
const cols =
static_cast<std::size_t
>(coefficients.
cols());
3288 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3289 RealSvdLeastSquares<Scalar> result;
3290 result.solution = detail::ColumnMajorLapackMatrix<Scalar>(cols, rhs_count);
3291 result.singular_values.resize(std::min(rows, cols));
3292 if (cols == 0 || rhs_count == 0)
3298 std::fill_n(result.solution.data(), result.solution.size(), Scalar{});
3302 std::size_t
const workspace_rows = std::max(rows, cols);
3303 detail::ColumnMajorLapackMatrix<Scalar> rhs_workspace(workspace_rows, rhs_count);
3306 for (std::size_t col = 0; col < rhs_count; ++col)
3308 rhs_workspace[
row, col] = right_hand_sides[
row, col];
3312 blas_int
const m = detail::checked_blas_int(rows);
3313 blas_int
const n = detail::checked_blas_int(cols);
3314 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3315 blas_int
const lda = std::max<blas_int>(1, m);
3316 blas_int
const ldb = detail::checked_blas_int(workspace_rows);
3318 blas_int
const iwork_size = detail::gelsd_iwork_size(m, n);
3319 std::vector<blas_int> iwork(
static_cast<std::size_t
>(iwork_size), 0);
3321 Scalar work_query{};
3322 blas_int
const query_lwork = -1;
3323 uni20::lapack::gelsd(m, n, nrhs, coefficients.
data(), lda, rhs_workspace.data(), ldb, result.singular_values.data(),
3324 rcond, rank, &work_query, query_lwork, iwork.data());
3326 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3327 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork), Scalar{});
3329 uni20::lapack::gelsd(m, n, nrhs, coefficients.
data(), lda, rhs_workspace.data(), ldb, result.singular_values.data(),
3330 rcond, rank, work.data(), lwork, iwork.data());
3334 throw std::runtime_error(
"LAPACK gelsd returned a negative rank");
3336 result.rank =
static_cast<std::size_t
>(rank);
3337 for (std::size_t
row = 0;
row < cols; ++
row)
3339 for (std::size_t col = 0; col < rhs_count; ++col)
3341 result.solution[
row, col] = rhs_workspace[
row, col];
3356template <uni20::LapackReal Scalar>
3357RealRankRevealingLeastSquares<Scalar>
3362 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3364 throw std::invalid_argument(
"real_rank_revealing_least_squares received incompatible right-hand sides");
3367 std::size_t
const rows =
static_cast<std::size_t
>(coefficients.
rows());
3368 std::size_t
const cols =
static_cast<std::size_t
>(coefficients.
cols());
3369 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3370 RealRankRevealingLeastSquares<Scalar> result;
3371 result.solution = detail::ColumnMajorLapackMatrix<Scalar>(cols, rhs_count);
3372 result.pivot_columns.resize(cols);
3373 std::iota(result.pivot_columns.begin(), result.pivot_columns.end(), std::size_t{0});
3374 if (cols == 0 || rhs_count == 0)
3380 std::fill_n(result.solution.data(), result.solution.size(), Scalar{});
3384 std::size_t
const workspace_rows = std::max(rows, cols);
3385 detail::ColumnMajorLapackMatrix<Scalar> rhs_workspace(workspace_rows, rhs_count);
3388 for (std::size_t col = 0; col < rhs_count; ++col)
3390 rhs_workspace[
row, col] = right_hand_sides[
row, col];
3394 blas_int
const m = detail::checked_blas_int(rows);
3395 blas_int
const n = detail::checked_blas_int(cols);
3396 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3397 blas_int
const lda = std::max<blas_int>(1, m);
3398 blas_int
const ldb = detail::checked_blas_int(workspace_rows);
3399 std::vector<blas_int> jpvt(cols, 0);
3402 Scalar work_query{};
3403 blas_int
const query_lwork = -1;
3404 uni20::lapack::gelsy(m, n, nrhs, coefficients.
data(), lda, rhs_workspace.data(), ldb, jpvt.data(), rcond, rank,
3405 &work_query, query_lwork);
3407 std::fill(jpvt.begin(), jpvt.end(), 0);
3408 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3409 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork), Scalar{});
3410 uni20::lapack::gelsy(m, n, nrhs, coefficients.
data(), lda, rhs_workspace.data(), ldb, jpvt.data(), rcond, rank,
3411 work.data(), lwork);
3415 throw std::runtime_error(
"LAPACK gelsy returned a negative rank");
3417 result.rank =
static_cast<std::size_t
>(rank);
3418 for (std::size_t col = 0; col < cols; ++col)
3420 if (jpvt[col] <= 0 ||
static_cast<std::size_t
>(jpvt[col]) > cols)
3422 throw std::runtime_error(
"LAPACK gelsy returned an invalid column pivot");
3424 result.pivot_columns[col] =
static_cast<std::size_t
>(jpvt[col] - 1);
3427 for (std::size_t
row = 0;
row < cols; ++
row)
3429 for (std::size_t col = 0; col < rhs_count; ++col)
3431 result.solution[
row, col] = rhs_workspace[
row, col];
3446template <uni20::LapackReal Scalar>
3447detail::ColumnMajorLapackMatrix<Scalar>
3452 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
3454 throw std::invalid_argument(
"real_symmetric_positive_definite_solve requires a square coefficient matrix");
3456 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3458 throw std::invalid_argument(
"real_symmetric_positive_definite_solve received incompatible right-hand sides");
3461 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
3462 if (n == 0 || right_hand_sides.
cols() == 0)
3464 return right_hand_sides;
3467 blas_int
const order = detail::checked_blas_int(n);
3468 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
3469 char const uplo = detail::lapack_uplo(triangle);
3472 return right_hand_sides;
3480template <uni20::LapackReal Scalar>
3481detail::ColumnMajorLapackMatrix<Scalar>
3485 if (!std::cmp_equal(factorization.
factors.rows(), factorization.
factors.cols()))
3487 throw std::invalid_argument(
"real_symmetric_positive_definite_solve requires square Cholesky factors");
3489 std::size_t
const n =
static_cast<std::size_t
>(factorization.
factors.rows());
3490 if (!std::cmp_equal(right_hand_sides.
rows(), n))
3492 throw std::invalid_argument(
"real_symmetric_positive_definite_solve received incompatible right-hand sides");
3494 if (n == 0 || right_hand_sides.
cols() == 0)
3496 return right_hand_sides;
3500 blas_int
const order = detail::checked_blas_int(n);
3501 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
3502 char const uplo = detail::lapack_uplo(factorization.
triangle);
3504 return right_hand_sides;
3517template <uni20::LapackReal Scalar>
3518RealRefinedLinearSolve<Scalar>
3523 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
3525 throw std::invalid_argument(
"real_symmetric_positive_definite_refined_solve requires a square coefficient matrix");
3527 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3529 throw std::invalid_argument(
3530 "real_symmetric_positive_definite_refined_solve received incompatible right-hand sides");
3533 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
3534 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3536 result.
solution = right_hand_sides;
3539 if (n == 0 || rhs_count == 0)
3545 blas_int
const order = detail::checked_blas_int(n);
3546 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3547 char const uplo = detail::lapack_uplo(triangle);
3551 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
3552 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3571template <uni20::LapackReal Scalar>
3572RealSymmetricPositiveDefiniteExpertLinearSolve<Scalar>
3577 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
3579 throw std::invalid_argument(
"real_symmetric_positive_definite_expert_solve requires a square coefficient matrix");
3581 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3583 throw std::invalid_argument(
"real_symmetric_positive_definite_expert_solve received incompatible right-hand sides");
3586 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
3587 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3594 if (n == 0 || rhs_count == 0)
3599 blas_int
const order = detail::checked_blas_int(n);
3600 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3601 char const uplo = detail::lapack_uplo(triangle);
3604 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
3605 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3608 'N', uplo, order, nrhs, coefficients.
data(), order, result.
factors.data(), order, equed, result.
scale.data(),
3625template <uni20::LapackReal Scalar>
3630 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
3632 throw std::invalid_argument(
3633 "real_symmetric_positive_definite_one_norm_reciprocal_condition_number requires a square matrix");
3636 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
3642 Scalar const original_one_norm = detail::symmetric_matrix_one_norm(matrix, triangle);
3643 blas_int
const order = detail::checked_blas_int(n);
3644 char const uplo = detail::lapack_uplo(triangle);
3646 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
3647 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3658template <uni20::LapackReal Scalar>
3662 if (!std::cmp_equal(factorization.
factors.rows(), factorization.
factors.cols()))
3664 throw std::invalid_argument(
3665 "real_symmetric_positive_definite_one_norm_reciprocal_condition_number requires square Cholesky factors");
3667 if (original_one_norm <
Scalar{})
3669 throw std::invalid_argument(
3670 "real_symmetric_positive_definite_one_norm_reciprocal_condition_number requires a nonnegative matrix norm");
3673 std::size_t
const n =
static_cast<std::size_t
>(factorization.
factors.rows());
3680 blas_int
const order = detail::checked_blas_int(n);
3681 char const uplo = detail::lapack_uplo(factorization.
triangle);
3682 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
3683 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3695template <uni20::LapackReal Scalar>
3696detail::ColumnMajorLapackMatrix<Scalar>
3700 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
3702 throw std::invalid_argument(
"real_symmetric_positive_definite_inverse requires a square matrix");
3705 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
3711 blas_int
const order = detail::checked_blas_int(n);
3712 char const uplo = detail::lapack_uplo(triangle);
3715 detail::mirror_selected_symmetric_triangle(matrix, triangle);
3727template <uni20::LapackReal Scalar>
3728RealSymmetricIndefiniteFactorization<Scalar>
3732 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
3734 throw std::invalid_argument(
"real_symmetric_indefinite_factorization requires a square matrix");
3737 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
3739 result.
factors = std::move(matrix);
3747 blas_int
const order = detail::checked_blas_int(n);
3748 char const uplo = detail::lapack_uplo(triangle);
3749 std::vector<blas_int> pivots(n);
3752 blas_int
const query_lwork = -1;
3755 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3756 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
3759 for (std::size_t index = 0; index < n; ++index)
3761 result.
pivot_blocks[index] =
static_cast<int>(pivots[index]);
3776template <uni20::LapackReal Scalar>
3777detail::ColumnMajorLapackMatrix<Scalar>
3782 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
3784 throw std::invalid_argument(
"real_symmetric_indefinite_solve requires a square coefficient matrix");
3786 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3788 throw std::invalid_argument(
"real_symmetric_indefinite_solve received incompatible right-hand sides");
3791 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
3792 if (n == 0 || right_hand_sides.
cols() == 0)
3794 return right_hand_sides;
3797 blas_int
const order = detail::checked_blas_int(n);
3798 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
3799 char const uplo = detail::lapack_uplo(triangle);
3800 std::vector<blas_int> pivots(n);
3803 blas_int
const query_lwork = -1;
3806 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3807 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
3810 return right_hand_sides;
3818template <uni20::LapackReal Scalar>
3819detail::ColumnMajorLapackMatrix<Scalar>
3823 if (!std::cmp_equal(factorization.
factors.rows(), factorization.
factors.cols()))
3825 throw std::invalid_argument(
"real_symmetric_indefinite_solve requires square Bunch-Kaufman factors");
3827 std::size_t
const n =
static_cast<std::size_t
>(factorization.
factors.rows());
3830 throw std::invalid_argument(
"real_symmetric_indefinite_solve received inconsistent pivot metadata");
3832 if (!std::cmp_equal(right_hand_sides.
rows(), n))
3834 throw std::invalid_argument(
"real_symmetric_indefinite_solve received incompatible right-hand sides");
3836 if (n == 0 || right_hand_sides.
cols() == 0)
3838 return right_hand_sides;
3842 std::vector<blas_int> pivots = detail::checked_symmetric_indefinite_pivots(factorization);
3843 blas_int
const order = detail::checked_blas_int(n);
3844 blas_int
const nrhs = detail::checked_blas_int(right_hand_sides.
cols());
3845 char const uplo = detail::lapack_uplo(factorization.
triangle);
3847 return right_hand_sides;
3860template <uni20::LapackReal Scalar>
3861RealRefinedLinearSolve<Scalar>
3866 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
3868 throw std::invalid_argument(
"real_symmetric_indefinite_refined_solve requires a square coefficient matrix");
3870 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3872 throw std::invalid_argument(
"real_symmetric_indefinite_refined_solve received incompatible right-hand sides");
3875 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
3876 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3878 result.
solution = right_hand_sides;
3881 if (n == 0 || rhs_count == 0)
3887 blas_int
const order = detail::checked_blas_int(n);
3888 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3889 char const uplo = detail::lapack_uplo(triangle);
3890 std::vector<blas_int> pivots(n);
3893 blas_int
const query_lwork = -1;
3896 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3897 std::vector<Scalar> factor_work(
static_cast<std::size_t
>(lwork),
Scalar{});
3901 std::vector<Scalar> refine_work(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order)),
Scalar{});
3902 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3904 right_hand_sides.
data(), order, result.
solution.data(), order,
3918template <uni20::LapackReal Scalar>
3919detail::ColumnMajorLapackMatrix<Scalar>
3923 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
3925 throw std::invalid_argument(
"real_symmetric_indefinite_inverse requires a square matrix");
3928 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
3934 blas_int
const order = detail::checked_blas_int(n);
3935 char const uplo = detail::lapack_uplo(triangle);
3936 std::vector<blas_int> pivots(n);
3939 blas_int
const query_lwork = -1;
3942 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
3943 std::vector<Scalar> factor_work(
static_cast<std::size_t
>(lwork),
Scalar{});
3946 std::vector<Scalar> inverse_work(
static_cast<std::size_t
>(std::max<blas_int>(1, order)),
Scalar{});
3948 detail::mirror_selected_symmetric_triangle(matrix, triangle);
3962template <uni20::LapackReal Scalar>
3963RealSymmetricIndefiniteExpertLinearSolve<Scalar>
3968 if (!std::cmp_equal(coefficients.
rows(), coefficients.
cols()))
3970 throw std::invalid_argument(
"real_symmetric_indefinite_expert_solve requires a square coefficient matrix");
3972 if (!std::cmp_equal(coefficients.
rows(), right_hand_sides.
rows()))
3974 throw std::invalid_argument(
"real_symmetric_indefinite_expert_solve received incompatible right-hand sides");
3977 std::size_t
const n =
static_cast<std::size_t
>(coefficients.
rows());
3978 std::size_t
const rhs_count =
static_cast<std::size_t
>(right_hand_sides.
cols());
3985 if (n == 0 || rhs_count == 0)
3990 blas_int
const order = detail::checked_blas_int(n);
3991 blas_int
const nrhs = detail::checked_blas_int(rhs_count);
3992 char const uplo = detail::lapack_uplo(triangle);
3993 std::vector<blas_int> pivots(n, 0);
3994 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
3998 blas_int
const query_lwork = -1;
4000 right_hand_sides.
data(), order, result.
solution.data(), order, rcond,
4002 query_lwork, iwork.data());
4004 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4005 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4007 'N', uplo, order, nrhs, coefficients.
data(), order, result.
factors.data(), order, pivots.data(),
4012 for (std::size_t index = 0; index < n; ++index)
4014 result.
pivot_blocks[index] =
static_cast<int>(pivots[index]);
4028template <uni20::LapackReal Scalar>
4032 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4034 throw std::invalid_argument(
4035 "real_symmetric_indefinite_one_norm_reciprocal_condition_number requires a square matrix");
4038 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4044 Scalar const original_one_norm = detail::symmetric_matrix_one_norm(matrix, triangle);
4045 blas_int
const order = detail::checked_blas_int(n);
4046 char const uplo = detail::lapack_uplo(triangle);
4047 std::vector<blas_int> pivots(n);
4050 blas_int
const query_lwork = -1;
4053 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4054 std::vector<Scalar> factor_work(
static_cast<std::size_t
>(lwork),
Scalar{});
4057 std::vector<Scalar> condition_work(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order)),
Scalar{});
4058 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
4060 condition_work.data(), iwork.data());
4070template <uni20::LapackReal Scalar>
4074 if (!std::cmp_equal(factorization.
factors.rows(), factorization.
factors.cols()))
4076 throw std::invalid_argument(
4077 "real_symmetric_indefinite_one_norm_reciprocal_condition_number requires square Bunch-Kaufman factors");
4079 if (original_one_norm <
Scalar{})
4081 throw std::invalid_argument(
4082 "real_symmetric_indefinite_one_norm_reciprocal_condition_number requires a nonnegative matrix norm");
4085 std::size_t
const n =
static_cast<std::size_t
>(factorization.
factors.rows());
4088 throw std::invalid_argument(
4089 "real_symmetric_indefinite_one_norm_reciprocal_condition_number received inconsistent pivot metadata");
4097 std::vector<blas_int> pivots = detail::checked_symmetric_indefinite_pivots(factorization);
4098 blas_int
const order = detail::checked_blas_int(n);
4099 char const uplo = detail::lapack_uplo(factorization.
triangle);
4100 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order)),
Scalar{});
4101 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
4116template <uni20::LapackReal Scalar>
4118 bool compute_vectors,
4121 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4123 throw std::invalid_argument(
"real_symmetric_eigensystem requires a square matrix");
4126 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4135 blas_int
const order = detail::checked_blas_int(n);
4136 char const jobz = compute_vectors ?
'V' :
'N';
4137 char const uplo = detail::lapack_uplo(triangle);
4139 blas_int
const query_lwork = -1;
4142 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4143 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4161template <uni20::LapackReal Scalar>
4162RealSymmetricEigensystem<Scalar>
4166 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4168 throw std::invalid_argument(
"real_symmetric_eigensystem_divide_and_conquer requires a square matrix");
4171 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4180 blas_int
const order = detail::checked_blas_int(n);
4181 char const jobz = compute_vectors ?
'V' :
'N';
4182 char const uplo = detail::lapack_uplo(triangle);
4184 blas_int iwork_query = 0;
4185 blas_int
const query_lwork = -1;
4187 &iwork_query, query_lwork);
4189 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4190 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
4191 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4192 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
4194 iwork.data(), liwork);
4213template <uni20::LapackReal Scalar>
4215 std::size_t first_index, std::size_t last_index,
4216 bool compute_vectors,
4219 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4221 throw std::invalid_argument(
"real_symmetric_eigensystem_index_range requires a square matrix");
4224 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4225 if (n == 0 || first_index > last_index || last_index >= n)
4227 throw std::invalid_argument(
"real_symmetric_eigensystem_index_range received an invalid index range");
4230 std::size_t
const selected = last_index - first_index + 1;
4234 blas_int
const order = detail::checked_blas_int(n);
4235 blas_int
const first = detail::checked_blas_int(first_index + 1);
4236 blas_int
const last = detail::checked_blas_int(last_index + 1);
4237 char const jobz = compute_vectors ?
'V' :
'N';
4238 char const range =
'I';
4239 char const uplo = detail::lapack_uplo(triangle);
4241 blas_int
const ldz = compute_vectors ? order : 1;
4242 std::vector<blas_int> support(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order)), 0);
4244 blas_int iwork_query = 0;
4245 blas_int selected_count = 0;
4246 blas_int
const query_lwork = -1;
4247 uni20::lapack::syevr(jobz, range, uplo, order, matrix.
data(), order,
Scalar{},
Scalar{}, first, last,
Scalar{},
4248 selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, support.
data(), &work_query,
4249 query_lwork, &iwork_query, query_lwork);
4251 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4252 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
4253 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4254 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
4256 uni20::lapack::syevr(jobz, range, uplo, order, matrix.
data(), order,
Scalar{},
Scalar{}, first, last,
Scalar{},
4257 selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, support.
data(), work.data(),
4258 lwork, iwork.data(), liwork);
4260 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
4262 throw std::runtime_error(
"LAPACK syevr returned an unexpected number of eigenvalues");
4281template <uni20::LapackReal Scalar>
4284 bool compute_vectors,
4287 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4289 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem requires a square matrix");
4291 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
4293 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem requires a square metric matrix");
4295 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
4297 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem received incompatible matrix sizes");
4300 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4309 blas_int
const order = detail::checked_blas_int(n);
4310 char const jobz = compute_vectors ?
'V' :
'N';
4311 char const uplo = detail::lapack_uplo(triangle);
4313 blas_int
const query_lwork = -1;
4315 &work_query, query_lwork);
4317 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4318 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4320 work.data(), lwork);
4339template <uni20::LapackReal Scalar>
4340RealSymmetricEigensystem<Scalar>
4343 bool compute_vectors,
MatrixFill triangle = MatrixFill::Upper)
4345 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4347 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem_divide_and_conquer requires a square matrix");
4349 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
4351 throw std::invalid_argument(
4352 "real_generalized_symmetric_eigensystem_divide_and_conquer requires a square metric matrix");
4354 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
4356 throw std::invalid_argument(
4357 "real_generalized_symmetric_eigensystem_divide_and_conquer received incompatible matrix sizes");
4360 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4369 blas_int
const order = detail::checked_blas_int(n);
4370 char const jobz = compute_vectors ?
'V' :
'N';
4371 char const uplo = detail::lapack_uplo(triangle);
4373 blas_int iwork_query = 0;
4374 blas_int
const query_lwork = -1;
4376 &work_query, query_lwork, &iwork_query, query_lwork);
4378 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4379 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
4380 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4381 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
4383 work.data(), lwork, iwork.data(), liwork);
4404template <uni20::LapackReal Scalar>
4407 std::size_t first_index, std::size_t last_index,
bool compute_vectors,
MatrixFill triangle = MatrixFill::Upper)
4409 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4411 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem_index_range requires a square matrix");
4413 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
4415 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem_index_range requires a square metric matrix");
4417 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
4419 throw std::invalid_argument(
4420 "real_generalized_symmetric_eigensystem_index_range received incompatible matrix sizes");
4423 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4424 if (n == 0 || first_index > last_index || last_index >= n)
4426 throw std::invalid_argument(
"real_generalized_symmetric_eigensystem_index_range received an invalid index range");
4429 std::size_t
const selected = last_index - first_index + 1;
4433 blas_int
const order = detail::checked_blas_int(n);
4434 blas_int
const first = detail::checked_blas_int(first_index + 1);
4435 blas_int
const last = detail::checked_blas_int(last_index + 1);
4436 char const jobz = compute_vectors ?
'V' :
'N';
4437 char const range =
'I';
4438 char const uplo = detail::lapack_uplo(triangle);
4440 blas_int
const ldz = compute_vectors ? order : 1;
4441 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 5 * order)), 0);
4442 std::vector<blas_int> ifail(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
4444 blas_int selected_count = 0;
4445 blas_int
const query_lwork = -1;
4446 uni20::lapack::sygvx(1, jobz, range, uplo, order, matrix.
data(), order, metric.
data(), order,
Scalar{},
Scalar{},
4448 &work_query, query_lwork, iwork.
data(), ifail.data());
4450 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4451 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4453 uni20::lapack::sygvx(1, jobz, range, uplo, order, matrix.
data(), order, metric.
data(), order,
Scalar{},
Scalar{},
4455 work.
data(), lwork, iwork.data(), ifail.data());
4457 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
4459 throw std::runtime_error(
"LAPACK sygvx returned an unexpected number of eigenvalues");
4476template <uni20::LapackComplexReal Real>
4477ComplexHermitianEigensystem<Real>
4481 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4483 throw std::invalid_argument(
"complex_hermitian_eigensystem requires a square matrix");
4487 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4496 blas_int
const order = detail::checked_blas_int(n);
4497 char const jobz = compute_vectors ?
'V' :
'N';
4498 char const uplo = detail::lapack_uplo(triangle);
4499 std::vector<Real> rwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order - 2)),
Real{});
4501 blas_int
const query_lwork = -1;
4505 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(std::real(work_query)));
4506 std::vector<Complex> work(
static_cast<std::size_t
>(lwork),
Complex{});
4522template <uni20::LapackComplexReal Real>
4523ComplexHermitianEigensystem<Real>
4525 bool compute_vectors,
MatrixFill triangle = MatrixFill::Upper)
4527 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4529 throw std::invalid_argument(
"complex_hermitian_eigensystem_divide_and_conquer requires a square matrix");
4533 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4542 blas_int
const order = detail::checked_blas_int(n);
4543 char const jobz = compute_vectors ?
'V' :
'N';
4544 char const uplo = detail::lapack_uplo(triangle);
4547 blas_int iwork_query = 0;
4548 blas_int
const query_lwork = -1;
4550 &rwork_query, query_lwork, &iwork_query, query_lwork);
4552 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(std::real(work_query)));
4553 blas_int
const lrwork = std::max<blas_int>(1,
static_cast<blas_int
>(rwork_query));
4554 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
4555 std::vector<Complex> work(
static_cast<std::size_t
>(lwork),
Complex{});
4556 std::vector<Real> rwork(
static_cast<std::size_t
>(lrwork),
Real{});
4557 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
4559 rwork.data(), lrwork, iwork.data(), liwork);
4575template <uni20::LapackComplexReal Real>
4576ComplexHermitianEigensystem<Real>
4578 std::size_t first_index, std::size_t last_index,
bool compute_vectors,
4581 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4583 throw std::invalid_argument(
"complex_hermitian_eigensystem_index_range requires a square matrix");
4587 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4588 if (n == 0 || first_index > last_index || last_index >= n)
4590 throw std::invalid_argument(
"complex_hermitian_eigensystem_index_range received an invalid index range");
4593 std::size_t
const selected = last_index - first_index + 1;
4597 blas_int
const order = detail::checked_blas_int(n);
4598 blas_int
const first = detail::checked_blas_int(first_index + 1);
4599 blas_int
const last = detail::checked_blas_int(last_index + 1);
4600 char const jobz = compute_vectors ?
'V' :
'N';
4601 char const range =
'I';
4602 char const uplo = detail::lapack_uplo(triangle);
4604 blas_int
const ldz = compute_vectors ? order : 1;
4605 std::vector<blas_int> support(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order)), 0);
4608 blas_int iwork_query = 0;
4609 blas_int selected_count = 0;
4610 blas_int
const query_lwork = -1;
4611 uni20::lapack::heevr(jobz, range, uplo, order, matrix.
data(), order,
Real{},
Real{}, first, last,
Real{},
4612 selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, support.
data(), &work_query,
4613 query_lwork, &rwork_query, query_lwork, &iwork_query, query_lwork);
4615 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(std::real(work_query)));
4616 blas_int
const lrwork = std::max<blas_int>(1,
static_cast<blas_int
>(rwork_query));
4617 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
4618 std::vector<Complex> work(
static_cast<std::size_t
>(lwork),
Complex{});
4619 std::vector<Real> rwork(
static_cast<std::size_t
>(lrwork),
Real{});
4620 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
4622 uni20::lapack::heevr(jobz, range, uplo, order, matrix.
data(), order,
Real{},
Real{}, first, last,
Real{},
4623 selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, support.
data(), work.data(),
4624 lwork, rwork.data(), lrwork, iwork.data(), liwork);
4626 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
4628 throw std::runtime_error(
"LAPACK heevr returned an unexpected number of eigenvalues");
4645template <uni20::LapackComplexReal Real>
4646ComplexHermitianEigensystem<Real>
4649 bool compute_vectors,
MatrixFill triangle = MatrixFill::Upper)
4651 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4653 throw std::invalid_argument(
"complex_generalized_hermitian_eigensystem requires a square matrix");
4655 if (!std::cmp_equal(metric.rows(), metric.cols()))
4657 throw std::invalid_argument(
"complex_generalized_hermitian_eigensystem requires a square metric matrix");
4659 if (!std::cmp_equal(matrix.
rows(), metric.rows()))
4661 throw std::invalid_argument(
"complex_generalized_hermitian_eigensystem received incompatible matrix sizes");
4665 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4674 blas_int
const order = detail::checked_blas_int(n);
4675 char const jobz = compute_vectors ?
'V' :
'N';
4676 char const uplo = detail::lapack_uplo(triangle);
4677 std::vector<Real> rwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 3 * order - 2)),
Real{});
4679 blas_int
const query_lwork = -1;
4681 &work_query, query_lwork, rwork.data());
4683 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(std::real(work_query)));
4684 std::vector<Complex> work(
static_cast<std::size_t
>(lwork),
Complex{});
4686 work.data(), lwork, rwork.data());
4701template <uni20::LapackComplexReal Real>
4707 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4709 throw std::invalid_argument(
4710 "complex_generalized_hermitian_eigensystem_divide_and_conquer requires a square matrix");
4712 if (!std::cmp_equal(metric.rows(), metric.cols()))
4714 throw std::invalid_argument(
4715 "complex_generalized_hermitian_eigensystem_divide_and_conquer requires a square metric matrix");
4717 if (!std::cmp_equal(matrix.
rows(), metric.rows()))
4719 throw std::invalid_argument(
4720 "complex_generalized_hermitian_eigensystem_divide_and_conquer received incompatible matrix sizes");
4724 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4733 blas_int
const order = detail::checked_blas_int(n);
4734 char const jobz = compute_vectors ?
'V' :
'N';
4735 char const uplo = detail::lapack_uplo(triangle);
4738 blas_int iwork_query = 0;
4739 blas_int
const query_lwork = -1;
4741 &work_query, query_lwork, &rwork_query, query_lwork, &iwork_query, query_lwork);
4743 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(std::real(work_query)));
4744 blas_int
const lrwork = std::max<blas_int>(1,
static_cast<blas_int
>(rwork_query));
4745 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
4746 std::vector<Complex> work(
static_cast<std::size_t
>(lwork),
Complex{});
4747 std::vector<Real> rwork(
static_cast<std::size_t
>(lrwork),
Real{});
4748 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
4750 work.data(), lwork, rwork.data(), lrwork, iwork.data(), liwork);
4767template <uni20::LapackComplexReal Real>
4768ComplexHermitianEigensystem<Real>
4771 std::size_t first_index, std::size_t last_index,
4772 bool compute_vectors,
MatrixFill triangle = MatrixFill::Upper)
4774 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
4776 throw std::invalid_argument(
"complex_generalized_hermitian_eigensystem_index_range requires a square matrix");
4778 if (!std::cmp_equal(metric.rows(), metric.cols()))
4780 throw std::invalid_argument(
4781 "complex_generalized_hermitian_eigensystem_index_range requires a square metric matrix");
4783 if (!std::cmp_equal(matrix.
rows(), metric.rows()))
4785 throw std::invalid_argument(
4786 "complex_generalized_hermitian_eigensystem_index_range received incompatible matrix sizes");
4790 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
4791 if (n == 0 || first_index > last_index || last_index >= n)
4793 throw std::invalid_argument(
4794 "complex_generalized_hermitian_eigensystem_index_range received an invalid index range");
4797 std::size_t
const selected = last_index - first_index + 1;
4801 blas_int
const order = detail::checked_blas_int(n);
4802 blas_int
const first = detail::checked_blas_int(first_index + 1);
4803 blas_int
const last = detail::checked_blas_int(last_index + 1);
4804 char const jobz = compute_vectors ?
'V' :
'N';
4805 char const range =
'I';
4806 char const uplo = detail::lapack_uplo(triangle);
4808 blas_int
const ldz = compute_vectors ? order : 1;
4809 std::vector<Real> rwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 7 * order)),
Real{});
4810 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 5 * order)), 0);
4811 std::vector<blas_int> ifail(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
4813 blas_int selected_count = 0;
4814 blas_int
const query_lwork = -1;
4815 uni20::lapack::hegvx(1, jobz, range, uplo, order, matrix.
data(), order, metric.data(), order,
Real{},
Real{}, first,
4816 last,
Real{}, selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, &work_query,
4817 query_lwork, rwork.
data(), iwork.data(), ifail.data());
4819 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(std::real(work_query)));
4820 std::vector<Complex> work(
static_cast<std::size_t
>(lwork),
Complex{});
4822 uni20::lapack::hegvx(1, jobz, range, uplo, order, matrix.
data(), order, metric.data(), order,
Real{},
Real{}, first,
4824 lwork, rwork.data(), iwork.data(), ifail.data());
4826 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
4828 throw std::runtime_error(
"LAPACK hegvx returned an unexpected number of eigenvalues");
4843template <uni20::LapackReal Scalar>
4846 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
4847 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
4848 std::size_t
const rank = std::min(rows, cols);
4852 result.
tau.resize(rank);
4859 blas_int
const m = detail::checked_blas_int(rows);
4860 blas_int
const n = detail::checked_blas_int(cols);
4861 blas_int
const lda = std::max<blas_int>(1, m);
4863 Scalar geqrf_work_query{};
4864 blas_int
const query_lwork = -1;
4867 blas_int
const geqrf_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(geqrf_work_query));
4868 std::vector<Scalar> geqrf_work(
static_cast<std::size_t
>(geqrf_lwork),
Scalar{});
4884template <uni20::LapackReal Scalar>
4890 std::size_t
const reflector_rows =
static_cast<std::size_t
>(factorization.
reflectors.rows());
4891 std::size_t
const reflector_cols =
static_cast<std::size_t
>(factorization.
reflectors.cols());
4892 if (factorization.
rank > std::min(reflector_rows, reflector_cols))
4894 throw std::invalid_argument(
"apply_real_qr_factor received inconsistent QR reflector dimensions");
4896 if (factorization.
tau.size() < factorization.
rank)
4898 throw std::invalid_argument(
"apply_real_qr_factor received too few QR scalar factors");
4903 throw std::invalid_argument(
"apply_real_qr_factor left application requires matching target row count");
4907 throw std::invalid_argument(
"apply_real_qr_factor right application requires matching target column count");
4909 if (target.
rows() == 0 || target.
cols() == 0 || factorization.
rank == 0)
4915 std::vector<Scalar> tau = factorization.
tau;
4916 blas_int
const m = detail::checked_blas_int(target.
rows());
4917 blas_int
const n = detail::checked_blas_int(target.
cols());
4918 blas_int
const k = detail::checked_blas_int(factorization.
rank);
4919 blas_int
const lda = std::max<blas_int>(1, detail::checked_blas_int(reflector_rows));
4920 blas_int
const ldc = std::max<blas_int>(1, m);
4921 char const side_char = detail::lapack_side(side);
4922 char const trans = detail::lapack_transpose(transpose);
4925 blas_int
const query_lwork = -1;
4926 uni20::lapack::ormqr(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, &work_query,
4929 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
4930 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
4931 uni20::lapack::ormqr(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, work.data(),
4943template <uni20::LapackReal Scalar>
4947 std::size_t
const rows =
static_cast<std::size_t
>(compact.reflectors.rows());
4948 std::size_t
const cols =
static_cast<std::size_t
>(compact.reflectors.cols());
4949 std::size_t
const rank = compact.rank;
4960 blas_int
const m = detail::checked_blas_int(rows);
4961 blas_int
const k = detail::checked_blas_int(rank);
4962 blas_int
const lda = std::max<blas_int>(1, m);
4964 for (std::size_t
row = 0;
row < rank; ++
row)
4966 for (std::size_t col =
row; col < cols; ++col)
4968 result.
r[
row, col] = compact.reflectors[
row, col];
4972 for (std::size_t col = 0; col < rank; ++col)
4974 for (std::size_t
row = 0;
row < rows; ++
row)
4976 result.
q[
row, col] = compact.reflectors[
row, col];
4980 Scalar orgqr_work_query{};
4981 blas_int
const query_lwork = -1;
4982 uni20::lapack::orgqr(m, k, k, result.
q.data(), lda, compact.tau.data(), &orgqr_work_query, query_lwork);
4984 blas_int
const orgqr_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(orgqr_work_query));
4985 std::vector<Scalar> orgqr_work(
static_cast<std::size_t
>(orgqr_lwork),
Scalar{});
4986 uni20::lapack::orgqr(m, k, k, result.
q.data(), lda, compact.tau.data(), orgqr_work.data(), orgqr_lwork);
4998template <uni20::LapackReal Scalar>
5001 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
5002 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
5003 std::size_t
const rank = std::min(rows, cols);
5007 result.
tau.resize(rank);
5014 blas_int
const m = detail::checked_blas_int(rows);
5015 blas_int
const n = detail::checked_blas_int(cols);
5016 blas_int
const lda = std::max<blas_int>(1, m);
5018 Scalar gelqf_work_query{};
5019 blas_int
const query_lwork = -1;
5022 blas_int
const gelqf_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(gelqf_work_query));
5023 std::vector<Scalar> gelqf_work(
static_cast<std::size_t
>(gelqf_lwork),
Scalar{});
5039template <uni20::LapackReal Scalar>
5045 std::size_t
const reflector_rows =
static_cast<std::size_t
>(factorization.
reflectors.rows());
5046 std::size_t
const reflector_cols =
static_cast<std::size_t
>(factorization.
reflectors.cols());
5047 if (factorization.
rank > std::min(reflector_rows, reflector_cols))
5049 throw std::invalid_argument(
"apply_real_lq_factor received inconsistent LQ reflector dimensions");
5051 if (factorization.
tau.size() < factorization.
rank)
5053 throw std::invalid_argument(
"apply_real_lq_factor received too few LQ scalar factors");
5058 throw std::invalid_argument(
"apply_real_lq_factor left application requires matching target row count");
5062 throw std::invalid_argument(
"apply_real_lq_factor right application requires matching target column count");
5064 if (target.
rows() == 0 || target.
cols() == 0 || factorization.
rank == 0)
5070 std::vector<Scalar> tau = factorization.
tau;
5071 blas_int
const m = detail::checked_blas_int(target.
rows());
5072 blas_int
const n = detail::checked_blas_int(target.
cols());
5073 blas_int
const k = detail::checked_blas_int(factorization.
rank);
5074 blas_int
const lda = std::max<blas_int>(1, detail::checked_blas_int(reflector_rows));
5075 blas_int
const ldc = std::max<blas_int>(1, m);
5076 char const side_char = detail::lapack_side(side);
5077 char const trans = detail::lapack_transpose(transpose);
5080 blas_int
const query_lwork = -1;
5081 uni20::lapack::ormlq(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, &work_query,
5084 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5085 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5086 uni20::lapack::ormlq(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, work.data(),
5098template <uni20::LapackReal Scalar>
5102 std::size_t
const rows =
static_cast<std::size_t
>(compact.reflectors.rows());
5103 std::size_t
const cols =
static_cast<std::size_t
>(compact.reflectors.cols());
5104 std::size_t
const rank = compact.rank;
5115 blas_int
const n = detail::checked_blas_int(cols);
5116 blas_int
const k = detail::checked_blas_int(rank);
5117 blas_int
const lda = std::max<blas_int>(1, k);
5119 for (std::size_t
row = 0;
row < rows; ++
row)
5121 for (std::size_t col = 0; col < rank && col <=
row; ++col)
5123 result.
l[
row, col] = compact.reflectors[
row, col];
5127 for (std::size_t
row = 0;
row < rank; ++
row)
5129 for (std::size_t col = 0; col < cols; ++col)
5131 result.
q[
row, col] = compact.reflectors[
row, col];
5135 Scalar orglq_work_query{};
5136 blas_int
const query_lwork = -1;
5137 uni20::lapack::orglq(k, n, k, result.
q.data(), lda, compact.tau.data(), &orglq_work_query, query_lwork);
5139 blas_int
const orglq_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(orglq_work_query));
5140 std::vector<Scalar> orglq_work(
static_cast<std::size_t
>(orglq_lwork),
Scalar{});
5141 uni20::lapack::orglq(k, n, k, result.
q.data(), lda, compact.tau.data(), orglq_work.data(), orglq_lwork);
5153template <uni20::LapackReal Scalar>
5156 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
5157 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
5158 std::size_t
const rank = std::min(rows, cols);
5162 result.
tau.resize(rank);
5169 blas_int
const m = detail::checked_blas_int(rows);
5170 blas_int
const n = detail::checked_blas_int(cols);
5171 blas_int
const lda = std::max<blas_int>(1, m);
5173 Scalar geqlf_work_query{};
5174 blas_int
const query_lwork = -1;
5177 blas_int
const geqlf_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(geqlf_work_query));
5178 std::vector<Scalar> geqlf_work(
static_cast<std::size_t
>(geqlf_lwork),
Scalar{});
5194template <uni20::LapackReal Scalar>
5200 std::size_t
const reflector_rows =
static_cast<std::size_t
>(factorization.
reflectors.rows());
5201 std::size_t
const reflector_cols =
static_cast<std::size_t
>(factorization.
reflectors.cols());
5202 if (factorization.
rank > std::min(reflector_rows, reflector_cols))
5204 throw std::invalid_argument(
"apply_real_ql_factor received inconsistent QL reflector dimensions");
5206 if (factorization.
tau.size() < factorization.
rank)
5208 throw std::invalid_argument(
"apply_real_ql_factor received too few QL scalar factors");
5213 throw std::invalid_argument(
"apply_real_ql_factor left application requires matching target row count");
5217 throw std::invalid_argument(
"apply_real_ql_factor right application requires matching target column count");
5219 if (target.
rows() == 0 || target.
cols() == 0 || factorization.
rank == 0)
5225 std::vector<Scalar> tau = factorization.
tau;
5226 blas_int
const m = detail::checked_blas_int(target.
rows());
5227 blas_int
const n = detail::checked_blas_int(target.
cols());
5228 blas_int
const k = detail::checked_blas_int(factorization.
rank);
5229 blas_int
const lda = std::max<blas_int>(1, detail::checked_blas_int(reflector_rows));
5230 blas_int
const ldc = std::max<blas_int>(1, m);
5231 char const side_char = detail::lapack_side(side);
5232 char const trans = detail::lapack_transpose(transpose);
5235 blas_int
const query_lwork = -1;
5236 uni20::lapack::ormql(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, &work_query,
5239 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5240 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5241 uni20::lapack::ormql(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, work.data(),
5253template <uni20::LapackReal Scalar>
5257 std::size_t
const rows =
static_cast<std::size_t
>(compact.reflectors.rows());
5258 std::size_t
const cols =
static_cast<std::size_t
>(compact.reflectors.cols());
5259 std::size_t
const rank = compact.rank;
5270 blas_int
const m = detail::checked_blas_int(rows);
5271 blas_int
const k = detail::checked_blas_int(rank);
5272 blas_int
const lda = std::max<blas_int>(1, m);
5274 std::size_t
const first_l_row = rows - rank;
5275 std::size_t
const diagonal_offset = cols - rank;
5276 for (std::size_t
row = 0;
row < rank; ++
row)
5278 std::size_t
const max_col = diagonal_offset +
row;
5279 for (std::size_t col = 0; col < cols && col <= max_col; ++col)
5281 result.
l[
row, col] = compact.reflectors[first_l_row +
row, col];
5285 std::size_t
const first_q_col = cols - rank;
5286 for (std::size_t col = 0; col < rank; ++col)
5288 for (std::size_t
row = 0;
row < rows; ++
row)
5290 result.
q[
row, col] = compact.reflectors[
row, first_q_col + col];
5294 Scalar orgql_work_query{};
5295 blas_int
const query_lwork = -1;
5296 uni20::lapack::orgql(m, k, k, result.
q.data(), lda, compact.tau.data(), &orgql_work_query, query_lwork);
5298 blas_int
const orgql_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(orgql_work_query));
5299 std::vector<Scalar> orgql_work(
static_cast<std::size_t
>(orgql_lwork),
Scalar{});
5300 uni20::lapack::orgql(m, k, k, result.
q.data(), lda, compact.tau.data(), orgql_work.data(), orgql_lwork);
5312template <uni20::LapackReal Scalar>
5315 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
5316 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
5317 std::size_t
const rank = std::min(rows, cols);
5321 result.
tau.resize(rank);
5328 blas_int
const m = detail::checked_blas_int(rows);
5329 blas_int
const n = detail::checked_blas_int(cols);
5330 blas_int
const lda = std::max<blas_int>(1, m);
5332 Scalar gerqf_work_query{};
5333 blas_int
const query_lwork = -1;
5336 blas_int
const gerqf_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(gerqf_work_query));
5337 std::vector<Scalar> gerqf_work(
static_cast<std::size_t
>(gerqf_lwork),
Scalar{});
5353template <uni20::LapackReal Scalar>
5359 std::size_t
const reflector_rows =
static_cast<std::size_t
>(factorization.
reflectors.rows());
5360 std::size_t
const reflector_cols =
static_cast<std::size_t
>(factorization.
reflectors.cols());
5361 if (factorization.
rank > std::min(reflector_rows, reflector_cols))
5363 throw std::invalid_argument(
"apply_real_rq_factor received inconsistent RQ reflector dimensions");
5365 if (factorization.
tau.size() < factorization.
rank)
5367 throw std::invalid_argument(
"apply_real_rq_factor received too few RQ scalar factors");
5372 throw std::invalid_argument(
"apply_real_rq_factor left application requires matching target row count");
5376 throw std::invalid_argument(
"apply_real_rq_factor right application requires matching target column count");
5378 if (target.
rows() == 0 || target.
cols() == 0 || factorization.
rank == 0)
5384 std::vector<Scalar> tau = factorization.
tau;
5385 blas_int
const m = detail::checked_blas_int(target.
rows());
5386 blas_int
const n = detail::checked_blas_int(target.
cols());
5387 blas_int
const k = detail::checked_blas_int(factorization.
rank);
5388 blas_int
const lda = std::max<blas_int>(1, detail::checked_blas_int(reflector_rows));
5389 blas_int
const ldc = std::max<blas_int>(1, m);
5390 char const side_char = detail::lapack_side(side);
5391 char const trans = detail::lapack_transpose(transpose);
5394 blas_int
const query_lwork = -1;
5395 uni20::lapack::ormrq(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, &work_query,
5398 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5399 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5400 uni20::lapack::ormrq(side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc, work.data(),
5412template <uni20::LapackReal Scalar>
5416 std::size_t
const rows =
static_cast<std::size_t
>(compact.reflectors.rows());
5417 std::size_t
const cols =
static_cast<std::size_t
>(compact.reflectors.cols());
5418 std::size_t
const rank = compact.rank;
5429 blas_int
const n = detail::checked_blas_int(cols);
5430 blas_int
const k = detail::checked_blas_int(rank);
5431 blas_int
const lda = std::max<blas_int>(1, k);
5433 std::size_t
const first_r_col = cols - rank;
5434 std::size_t
const diagonal_offset = rows - rank;
5435 for (std::size_t
row = 0;
row < rows; ++
row)
5437 for (std::size_t col = 0; col < rank; ++col)
5439 if (
row <= diagonal_offset + col)
5441 result.
r[
row, col] = compact.reflectors[
row, first_r_col + col];
5446 std::size_t
const first_q_row = rows - rank;
5447 for (std::size_t
row = 0;
row < rank; ++
row)
5449 for (std::size_t col = 0; col < cols; ++col)
5451 result.
q[
row, col] = compact.reflectors[first_q_row +
row, col];
5455 Scalar orgrq_work_query{};
5456 blas_int
const query_lwork = -1;
5457 uni20::lapack::orgrq(k, n, k, result.
q.data(), lda, compact.tau.data(), &orgrq_work_query, query_lwork);
5459 blas_int
const orgrq_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(orgrq_work_query));
5460 std::vector<Scalar> orgrq_work(
static_cast<std::size_t
>(orgrq_lwork),
Scalar{});
5461 uni20::lapack::orgrq(k, n, k, result.
q.data(), lda, compact.tau.data(), orgrq_work.data(), orgrq_lwork);
5474template <uni20::LapackReal Scalar>
5477 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
5478 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
5479 std::size_t
const rank = std::min(rows, cols);
5485 result.
offdiagonal.resize(rank > 0 ? rank - 1 : 0);
5486 result.
tauq.resize(rank);
5487 result.
taup.resize(rank);
5488 result.
upper = rows >= cols;
5495 blas_int
const m = detail::checked_blas_int(rows);
5496 blas_int
const n = detail::checked_blas_int(cols);
5497 blas_int
const lda = std::max<blas_int>(1, m);
5500 blas_int
const query_lwork = -1;
5502 result.
tauq.data(), result.
taup.data(), &work_query, query_lwork);
5504 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5505 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5507 result.
tauq.data(), result.
taup.data(), work.data(), lwork);
5509 for (std::size_t index = 0; index < rank; ++index)
5513 for (std::size_t index = 0; index + 1 < rank; ++index)
5538template <uni20::LapackReal Scalar>
5542 std::size_t
const order = diagonal.size();
5543 if (offdiagonal.size() != (order > 0 ? order - 1 : 0))
5545 throw std::invalid_argument(
"real_bidiagonal_singular_values received inconsistent bidiagonal dimensions");
5552 blas_int
const n = detail::checked_blas_int(order);
5553 blas_int
const zero = 0;
5554 blas_int
const dummy_ld = 1;
5556 Scalar* e = offdiagonal.empty() ? &dummy : offdiagonal.data();
5557 std::vector<Scalar> work(
static_cast<std::size_t
>(std::max<blas_int>(1, 4 * n)),
Scalar{});
5558 uni20::lapack::bdsqr(upper ?
'U' :
'L', n, zero, zero, zero, diagonal.data(), e, &dummy, dummy_ld, &dummy, dummy_ld,
5559 &dummy, dummy_ld, work.data());
5568template <uni20::LapackReal Scalar>
5587template <uni20::LapackReal Scalar>
5589 bool compute_vectors,
bool upper =
true)
5591 std::size_t
const order = diagonal.size();
5592 if (offdiagonal.size() != (order > 0 ? order - 1 : 0))
5594 throw std::invalid_argument(
"real_bidiagonal_svd received inconsistent bidiagonal dimensions");
5606 blas_int
const n = detail::checked_blas_int(order);
5607 char const compq = compute_vectors ?
'I' :
'N';
5610 blas_int
const leading_dimension = compute_vectors ? n : 1;
5611 Scalar dummy_subdiagonal{};
5612 Scalar* e = offdiagonal.empty() ? &dummy_subdiagonal : offdiagonal.data();
5613 std::vector<Scalar> q(1,
Scalar{});
5614 std::vector<blas_int> iq(1, 0);
5615 std::size_t
const work_size = compute_vectors ? 3 * order * order + 4 * order : 4 * order;
5616 std::vector<Scalar> work(std::max<std::size_t>(1, work_size),
Scalar{});
5617 std::vector<blas_int> iwork(std::max<std::size_t>(1, 8 * order), 0);
5619 vt.
data(), leading_dimension, q.
data(), iq.data(), work.data(), iwork.data());
5632template <uni20::LapackReal Scalar>
5654template <uni20::LapackReal Scalar>
5656 std::size_t first_index, std::size_t last_index,
5657 bool compute_vectors,
bool upper =
true)
5659 std::size_t
const order = diagonal.size();
5660 if (offdiagonal.size() != (order > 0 ? order - 1 : 0))
5662 throw std::invalid_argument(
"real_bidiagonal_svd_index_range received inconsistent bidiagonal dimensions");
5664 if (order == 0 || first_index > last_index || last_index >= order)
5666 throw std::invalid_argument(
"real_bidiagonal_svd_index_range received an invalid index range");
5669 std::size_t
const selected = last_index - first_index + 1;
5672 blas_int
const n = detail::checked_blas_int(order);
5673 blas_int
const first = detail::checked_blas_int(first_index + 1);
5674 blas_int
const last = detail::checked_blas_int(last_index + 1);
5675 char const jobz = compute_vectors ?
'V' :
'N';
5676 char const range =
'I';
5677 Scalar dummy_subdiagonal{};
5678 Scalar* e = offdiagonal.empty() ? &dummy_subdiagonal : offdiagonal.data();
5681 std::vector<Scalar> singular_values_workspace(order,
Scalar{});
5683 blas_int
const ldz = compute_vectors ? detail::checked_blas_int(2 * order) : 1;
5684 std::vector<Scalar> work(std::max<std::size_t>(1, 14 * order),
Scalar{});
5685 std::vector<blas_int> iwork(std::max<std::size_t>(1, 12 * order), 0);
5686 blas_int selected_count = 0;
5687 uni20::lapack::bdsvdx(upper ?
'U' :
'L', jobz, range, n, diagonal.data(), e,
Scalar{},
Scalar{}, first, last,
5688 selected_count, singular_values_workspace.data(), z.data(), ldz, work.data(), iwork.data());
5690 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
5692 throw std::runtime_error(
"LAPACK bdsvdx returned an unexpected number of singular values");
5695 result.
singular_values.assign(singular_values_workspace.begin(), singular_values_workspace.begin() + selected_count);
5697 if (!compute_vectors)
5706 for (std::size_t col = 0; col < selected; ++col)
5708 for (std::size_t
row = 0;
row < order; ++
row)
5710 result.
u[
row, col] = z[
row, col];
5711 result.
vt[col,
row] = z[order +
row, col];
5725template <uni20::LapackReal Scalar>
5727 std::size_t first_index, std::size_t last_index,
5728 bool compute_vectors)
5731 compute_vectors, reduction.
upper);
5739template <uni20::LapackReal Scalar>
5740detail::ColumnMajorLapackMatrix<Scalar>
5743 std::size_t
const rows =
static_cast<std::size_t
>(reduction.
reflectors.rows());
5744 std::size_t
const cols =
static_cast<std::size_t
>(reduction.
reflectors.cols());
5747 if (rows == 0 || cols == 0)
5751 if (reduction.
tauq.size() < std::min(rows, cols))
5753 throw std::invalid_argument(
"real_bidiagonal_left_orthogonal_factor received too few Q scalar factors");
5756 for (std::size_t col = 0; col < std::min(cols, rows); ++col)
5758 for (std::size_t
row = 0;
row < rows; ++
row)
5764 blas_int
const m = detail::checked_blas_int(rows);
5765 blas_int
const n = detail::checked_blas_int(rows);
5766 blas_int
const k = detail::checked_blas_int(cols);
5767 blas_int
const lda = std::max<blas_int>(1, m);
5770 blas_int
const query_lwork = -1;
5774 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5775 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5788template <uni20::LapackReal Scalar>
5789detail::ColumnMajorLapackMatrix<Scalar>
5792 std::size_t
const rows =
static_cast<std::size_t
>(reduction.
reflectors.rows());
5793 std::size_t
const cols =
static_cast<std::size_t
>(reduction.
reflectors.cols());
5796 if (rows == 0 || cols == 0)
5800 if (reduction.
taup.size() < std::min(rows, cols))
5802 throw std::invalid_argument(
"real_bidiagonal_right_orthogonal_factor_transpose received too few P scalar factors");
5805 for (std::size_t col = 0; col < cols; ++col)
5807 for (std::size_t
row = 0;
row < std::min(rows, cols); ++
row)
5813 blas_int
const m = detail::checked_blas_int(cols);
5814 blas_int
const n = detail::checked_blas_int(cols);
5815 blas_int
const k = detail::checked_blas_int(rows);
5816 blas_int
const lda = std::max<blas_int>(1, m);
5819 blas_int
const query_lwork = -1;
5823 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5824 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5840template <uni20::LapackReal Scalar>
5841detail::ColumnMajorLapackMatrix<Scalar>
5846 std::size_t
const rows =
static_cast<std::size_t
>(reduction.
reflectors.rows());
5847 std::size_t
const cols =
static_cast<std::size_t
>(reduction.
reflectors.cols());
5848 std::size_t
const rank = std::min(rows, cols);
5849 if (reduction.
tauq.size() < rank)
5851 throw std::invalid_argument(
"apply_real_bidiagonal_left_factor received too few Q scalar factors");
5855 throw std::invalid_argument(
5856 "apply_real_bidiagonal_left_factor left application requires matching target row count");
5860 throw std::invalid_argument(
5861 "apply_real_bidiagonal_left_factor right application requires matching target column count");
5863 if (target.
rows() == 0 || target.
cols() == 0 || cols == 0)
5869 std::vector<Scalar> tau = reduction.
tauq;
5870 blas_int
const m = detail::checked_blas_int(target.
rows());
5871 blas_int
const n = detail::checked_blas_int(target.
cols());
5872 blas_int
const k = detail::checked_blas_int(cols);
5873 blas_int
const lda = std::max<blas_int>(1, detail::checked_blas_int(rows));
5874 blas_int
const ldc = std::max<blas_int>(1, m);
5875 char const side_char = detail::lapack_side(side);
5876 char const trans = detail::lapack_transpose(transpose);
5879 blas_int
const query_lwork = -1;
5880 uni20::lapack::ormbr(
'Q', side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc,
5881 &work_query, query_lwork);
5883 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5884 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5885 uni20::lapack::ormbr(
'Q', side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc,
5886 work.data(), lwork);
5900template <uni20::LapackReal Scalar>
5901detail::ColumnMajorLapackMatrix<Scalar>
5906 std::size_t
const rows =
static_cast<std::size_t
>(reduction.
reflectors.rows());
5907 std::size_t
const cols =
static_cast<std::size_t
>(reduction.
reflectors.cols());
5908 std::size_t
const rank = std::min(rows, cols);
5909 if (reduction.
taup.size() < rank)
5911 throw std::invalid_argument(
"apply_real_bidiagonal_right_factor received too few P scalar factors");
5915 throw std::invalid_argument(
5916 "apply_real_bidiagonal_right_factor left application requires matching target row count");
5920 throw std::invalid_argument(
5921 "apply_real_bidiagonal_right_factor right application requires matching target column count");
5923 if (target.
rows() == 0 || target.
cols() == 0 || rows == 0)
5929 std::vector<Scalar> tau = reduction.
taup;
5930 blas_int
const m = detail::checked_blas_int(target.
rows());
5931 blas_int
const n = detail::checked_blas_int(target.
cols());
5932 blas_int
const k = detail::checked_blas_int(rows);
5933 blas_int
const lda = std::max<blas_int>(1, detail::checked_blas_int(rows));
5934 blas_int
const ldc = std::max<blas_int>(1, m);
5935 char const side_char = detail::lapack_side(side);
5936 char const trans = detail::lapack_transpose(transpose);
5939 blas_int
const query_lwork = -1;
5940 uni20::lapack::ormbr(
'P', side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc,
5941 &work_query, query_lwork);
5943 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5944 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5945 uni20::lapack::ormbr(
'P', side_char, trans, m, n, k, reflectors.
data(), lda, tau.data(), target.
data(), ldc,
5946 work.data(), lwork);
5959template <uni20::LapackReal Scalar>
5962 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
5964 throw std::invalid_argument(
"real_hessenberg_reduction requires a square matrix");
5967 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
5971 result.
tau.resize(n > 0 ? n - 1 : 0);
5981 blas_int
const order = detail::checked_blas_int(n);
5982 blas_int
const first = 1;
5983 blas_int
const last = order;
5986 blas_int
const query_lwork = -1;
5989 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
5990 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
5996 for (std::size_t col = 0; col < n; ++col)
5998 for (std::size_t
row = col + 2;
row < n; ++
row)
6012template <uni20::LapackReal Scalar>
6013detail::ColumnMajorLapackMatrix<Scalar>
6018 throw std::invalid_argument(
"real_hessenberg_orthogonal_factor requires square compact reflector storage");
6021 std::size_t
const n =
static_cast<std::size_t
>(reduction.
reflectors.rows());
6022 if (reduction.
tau.size() != (n > 0 ? n - 1 : 0))
6024 throw std::invalid_argument(
"real_hessenberg_orthogonal_factor received inconsistent tau data");
6028 throw std::invalid_argument(
"real_hessenberg_orthogonal_factor received invalid active interval");
6032 for (std::size_t diagonal = 0; diagonal < n; ++diagonal)
6034 q[diagonal, diagonal] =
Scalar{1};
6042 blas_int
const order = detail::checked_blas_int(n);
6043 blas_int
const first = detail::checked_blas_int(reduction.
first + 1);
6044 blas_int
const last = detail::checked_blas_int(reduction.
last_exclusive);
6047 blas_int
const query_lwork = -1;
6050 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6051 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6066template <uni20::LapackReal Scalar>
6073 throw std::invalid_argument(
"apply_real_hessenberg_orthogonal_factor requires square compact reflector storage");
6076 std::size_t
const order_size =
static_cast<std::size_t
>(reduction.
reflectors.rows());
6077 if (reduction.
tau.size() != (order_size > 0 ? order_size - 1 : 0))
6079 throw std::invalid_argument(
"apply_real_hessenberg_orthogonal_factor received inconsistent tau data");
6083 throw std::invalid_argument(
"apply_real_hessenberg_orthogonal_factor received invalid active interval");
6087 throw std::invalid_argument(
"apply_real_hessenberg_orthogonal_factor left application requires matching rows");
6091 throw std::invalid_argument(
"apply_real_hessenberg_orthogonal_factor right application requires matching columns");
6093 if (target.
rows() == 0 || target.
cols() == 0 || order_size <= 1)
6099 blas_int
const m = detail::checked_blas_int(target.
rows());
6100 blas_int
const n = detail::checked_blas_int(target.
cols());
6101 blas_int
const order = detail::checked_blas_int(order_size);
6102 blas_int
const first = detail::checked_blas_int(reduction.
first + 1);
6103 blas_int
const last = detail::checked_blas_int(reduction.
last_exclusive);
6104 blas_int
const lda = std::max<blas_int>(1, order);
6105 blas_int
const ldc = std::max<blas_int>(1, m);
6106 char const side_char = detail::lapack_side(side);
6107 char const trans = detail::lapack_transpose(transpose);
6110 blas_int
const query_lwork = -1;
6111 uni20::lapack::ormhr(side_char, trans, m, n, first, last, reflectors.
data(), lda, reduction.
tau.data(), target.
data(),
6112 ldc, &work_query, query_lwork);
6114 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6115 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6116 uni20::lapack::ormhr(side_char, trans, m, n, first, last, reflectors.
data(), lda, reduction.
tau.data(), target.
data(),
6117 ldc, work.data(), lwork);
6132template <uni20::LapackReal Scalar>
6133RealSymmetricTridiagonalReduction<Scalar>
6137 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
6139 throw std::invalid_argument(
"real_symmetric_tridiagonal_reduction requires a square matrix");
6142 char const uplo = detail::lapack_uplo(triangle);
6143 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
6148 result.
tau.resize(n > 0 ? n - 1 : 0);
6156 blas_int
const order = detail::checked_blas_int(n);
6158 blas_int
const query_lwork = -1;
6160 result.
tau.data(), &work_query, query_lwork);
6162 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6163 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6165 result.
tau.data(), work.data(), lwork);
6170 for (std::size_t index = 0; index < n; ++index)
6174 for (std::size_t index = 0; index + 1 < n; ++index)
6189template <uni20::LapackReal Scalar>
6190detail::ColumnMajorLapackMatrix<Scalar>
6195 throw std::invalid_argument(
6196 "real_symmetric_tridiagonal_orthogonal_factor requires square compact reflector storage");
6199 std::size_t
const n =
static_cast<std::size_t
>(reduction.
reflectors.rows());
6200 if (reduction.
diagonal.size() != n || reduction.
offdiagonal.size() != (n > 0 ? n - 1 : 0) ||
6201 reduction.
tau.size() != (n > 0 ? n - 1 : 0))
6203 throw std::invalid_argument(
"real_symmetric_tridiagonal_orthogonal_factor received inconsistent reduction data");
6207 for (std::size_t diagonal = 0; diagonal < n; ++diagonal)
6209 q[diagonal, diagonal] =
Scalar{1};
6217 blas_int
const order = detail::checked_blas_int(n);
6218 char const uplo = detail::lapack_uplo(reduction.
triangle);
6221 blas_int
const query_lwork = -1;
6224 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6225 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6241template <uni20::LapackReal Scalar>
6248 throw std::invalid_argument(
6249 "apply_real_symmetric_tridiagonal_orthogonal_factor requires square compact reflector storage");
6252 std::size_t
const order_size =
static_cast<std::size_t
>(reduction.
reflectors.rows());
6253 if (reduction.
diagonal.size() != order_size ||
6254 reduction.
offdiagonal.size() != (order_size > 0 ? order_size - 1 : 0) ||
6255 reduction.
tau.size() != (order_size > 0 ? order_size - 1 : 0))
6257 throw std::invalid_argument(
6258 "apply_real_symmetric_tridiagonal_orthogonal_factor received inconsistent reduction data");
6262 throw std::invalid_argument(
6263 "apply_real_symmetric_tridiagonal_orthogonal_factor left application requires matching rows");
6267 throw std::invalid_argument(
6268 "apply_real_symmetric_tridiagonal_orthogonal_factor right application requires matching columns");
6270 if (target.
rows() == 0 || target.
cols() == 0 || order_size <= 1)
6276 blas_int
const m = detail::checked_blas_int(target.
rows());
6277 blas_int
const n = detail::checked_blas_int(target.
cols());
6278 blas_int
const order = detail::checked_blas_int(order_size);
6279 blas_int
const lda = std::max<blas_int>(1, order);
6280 blas_int
const ldc = std::max<blas_int>(1, m);
6281 char const side_char = detail::lapack_side(side);
6282 char const uplo = detail::lapack_uplo(reduction.
triangle);
6283 char const trans = detail::lapack_transpose(transpose);
6286 blas_int
const query_lwork = -1;
6287 uni20::lapack::ormtr(side_char, uplo, trans, m, n, reflectors.
data(), lda, reduction.
tau.data(), target.
data(), ldc,
6288 &work_query, query_lwork);
6290 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6291 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6292 uni20::lapack::ormtr(side_char, uplo, trans, m, n, reflectors.
data(), lda, reduction.
tau.data(), target.
data(), ldc,
6293 work.data(), lwork);
6304template <uni20::LapackReal Scalar>
6307 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
6308 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
6309 std::size_t
const rank = std::min(rows, cols);
6322 blas_int
const m = detail::checked_blas_int(rows);
6323 blas_int
const n = detail::checked_blas_int(cols);
6324 blas_int
const k = detail::checked_blas_int(rank);
6325 blas_int
const lda = std::max<blas_int>(1, m);
6326 std::vector<Scalar> tau(rank,
Scalar{});
6327 std::vector<blas_int> jpvt(cols, 0);
6329 Scalar geqp3_work_query{};
6330 blas_int
const query_lwork = -1;
6333 std::fill(jpvt.begin(), jpvt.end(), 0);
6334 blas_int
const geqp3_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(geqp3_work_query));
6335 std::vector<Scalar> geqp3_work(
static_cast<std::size_t
>(geqp3_lwork),
Scalar{});
6338 for (std::size_t col = 0; col < cols; ++col)
6340 if (jpvt[col] <= 0 ||
static_cast<std::size_t
>(jpvt[col]) > cols)
6342 throw std::runtime_error(
"LAPACK geqp3 returned an invalid column pivot");
6344 result.
pivot_columns[col] =
static_cast<std::size_t
>(jpvt[col] - 1);
6347 for (std::size_t
row = 0;
row < rank; ++
row)
6349 for (std::size_t col =
row; col < cols; ++col)
6351 result.
r[
row, col] = matrix[
row, col];
6355 for (std::size_t col = 0; col < rank; ++col)
6357 for (std::size_t
row = 0;
row < rows; ++
row)
6359 result.
q[
row, col] = matrix[
row, col];
6363 Scalar orgqr_work_query{};
6366 blas_int
const orgqr_lwork = std::max<blas_int>(1,
static_cast<blas_int
>(orgqr_work_query));
6367 std::vector<Scalar> orgqr_work(
static_cast<std::size_t
>(orgqr_lwork),
Scalar{});
6382template <uni20::LapackReal Scalar>
6384 bool compute_vectors)
6386 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
6387 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
6388 std::size_t
const singular_value_count = std::min(rows, cols);
6392 if (singular_value_count == 0)
6401 blas_int
const m = detail::checked_blas_int(rows);
6402 blas_int
const n = detail::checked_blas_int(cols);
6403 blas_int
const lda = std::max<blas_int>(1, m);
6404 char const jobu = compute_vectors ?
'A' :
'N';
6405 char const jobvt = compute_vectors ?
'A' :
'N';
6408 blas_int
const ldu = compute_vectors ? std::max<blas_int>(1, m) : 1;
6409 blas_int
const ldvt = compute_vectors ? std::max<blas_int>(1, n) : 1;
6412 blas_int
const query_lwork = -1;
6414 right_transpose.
data(), ldvt, &work_query, query_lwork);
6416 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6417 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6419 right_transpose.
data(), ldvt, work.data(), lwork);
6437template <uni20::LapackReal Scalar>
6438RealSingularValueDecomposition<Scalar>
6440 bool compute_vectors)
6442 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
6443 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
6444 std::size_t
const singular_value_count = std::min(rows, cols);
6448 if (singular_value_count == 0)
6457 blas_int
const m = detail::checked_blas_int(rows);
6458 blas_int
const n = detail::checked_blas_int(cols);
6459 blas_int
const lda = std::max<blas_int>(1, m);
6460 char const jobz = compute_vectors ?
'A' :
'N';
6463 blas_int
const ldu = compute_vectors ? std::max<blas_int>(1, m) : 1;
6464 blas_int
const ldvt = compute_vectors ? std::max<blas_int>(1, n) : 1;
6465 std::vector<blas_int> iwork(
6466 static_cast<std::size_t
>(std::max<blas_int>(1, 8 * detail::checked_blas_int(singular_value_count))));
6469 blas_int
const query_lwork = -1;
6471 right_transpose.
data(), ldvt, &work_query, query_lwork, iwork.data());
6473 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6474 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6476 right_transpose.
data(), ldvt, work.data(), lwork, iwork.data());
6496template <uni20::LapackReal Scalar>
6497RealSingularValueDecomposition<Scalar>
6499 std::size_t last_index,
bool compute_vectors)
6501 std::size_t
const rows =
static_cast<std::size_t
>(matrix.
rows());
6502 std::size_t
const cols =
static_cast<std::size_t
>(matrix.
cols());
6503 std::size_t
const singular_value_count = std::min(rows, cols);
6504 if (singular_value_count == 0 || first_index > last_index || last_index >= singular_value_count)
6506 throw std::invalid_argument(
"real_singular_value_decomposition_index_range received an invalid index range");
6509 std::size_t
const selected = last_index - first_index + 1;
6512 blas_int
const m = detail::checked_blas_int(rows);
6513 blas_int
const n = detail::checked_blas_int(cols);
6514 blas_int
const lda = std::max<blas_int>(1, m);
6515 blas_int
const first = detail::checked_blas_int(first_index + 1);
6516 blas_int
const last = detail::checked_blas_int(last_index + 1);
6517 char const jobu = compute_vectors ?
'V' :
'N';
6518 char const jobvt = compute_vectors ?
'V' :
'N';
6519 char const range =
'I';
6520 std::vector<Scalar> singular_values_workspace(singular_value_count,
Scalar{});
6523 blas_int
const ldu = compute_vectors ? std::max<blas_int>(1, m) : 1;
6524 blas_int
const ldvt = compute_vectors ? detail::checked_blas_int(selected) : 1;
6525 std::vector<blas_int> iwork(
6526 static_cast<std::size_t
>(std::max<blas_int>(1, 12 * detail::checked_blas_int(singular_value_count))));
6527 blas_int selected_count = 0;
6530 blas_int
const query_lwork = -1;
6531 uni20::lapack::gesvdx(jobu, jobvt, range, m, n, matrix.
data(), lda,
Scalar{},
Scalar{}, first, last, selected_count,
6532 singular_values_workspace.data(), left.data(), ldu, right_transpose.data(), ldvt, &work_query,
6533 query_lwork, iwork.data());
6535 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6536 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6537 uni20::lapack::gesvdx(jobu, jobvt, range, m, n, matrix.
data(), lda,
Scalar{},
Scalar{}, first, last, selected_count,
6538 singular_values_workspace.data(), left.data(), ldu, right_transpose.data(), ldvt, work.data(),
6539 lwork, iwork.data());
6541 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
6543 throw std::runtime_error(
"LAPACK gesvdx returned an unexpected number of singular values");
6546 result.
singular_values.assign(singular_values_workspace.begin(), singular_values_workspace.begin() + selected_count);
6562template <uni20::LapackReal Scalar>
6564 std::vector<Scalar> subdiagonal,
6565 bool compute_vectors)
6567 std::size_t
const n = diagonal.size();
6568 if (subdiagonal.size() + 1 != n && !(n == 0 && subdiagonal.empty()))
6570 throw std::invalid_argument(
6571 "symmetric_tridiagonal_eigensystem_divide_and_conquer received inconsistent diagonal sizes");
6582 blas_int
const order = detail::checked_blas_int(n);
6583 char const jobz = compute_vectors ?
'V' :
'N';
6585 blas_int
const ldz = compute_vectors ? order : 1;
6586 Scalar dummy_subdiagonal{};
6587 Scalar* e = subdiagonal.empty() ? &dummy_subdiagonal : subdiagonal.data();
6590 blas_int iwork_query = 0;
6591 blas_int
const query_lwork = -1;
6595 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6596 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
6597 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6598 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
6620template <uni20::LapackReal Scalar>
6621TridiagonalEigensystem<Scalar>
6623 std::size_t first_index, std::size_t last_index,
bool compute_vectors)
6625 std::size_t
const n = diagonal.size();
6626 if (subdiagonal.size() + 1 != n)
6628 throw std::invalid_argument(
"symmetric_tridiagonal_eigensystem_index_range received inconsistent diagonal sizes");
6630 if (n == 0 || first_index > last_index || last_index >= n)
6632 throw std::invalid_argument(
"symmetric_tridiagonal_eigensystem_index_range received an invalid index range");
6635 std::size_t
const selected = last_index - first_index + 1;
6639 blas_int
const order = detail::checked_blas_int(n);
6640 blas_int
const first = detail::checked_blas_int(first_index + 1);
6641 blas_int
const last = detail::checked_blas_int(last_index + 1);
6642 char const jobz = compute_vectors ?
'V' :
'N';
6643 char const range =
'I';
6645 blas_int
const ldz = compute_vectors ? order : 1;
6646 std::vector<blas_int> support(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order)), 0);
6647 Scalar dummy_subdiagonal{};
6648 Scalar* e = subdiagonal.empty() ? &dummy_subdiagonal : subdiagonal.data();
6650 blas_int iwork_query = 0;
6651 blas_int selected_count = 0;
6652 blas_int
const query_lwork = -1;
6653 uni20::lapack::stevr(jobz, range, order, diagonal.data(), e,
Scalar{},
Scalar{}, first, last,
Scalar{},
6654 selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, support.
data(), &work_query,
6655 query_lwork, &iwork_query, query_lwork);
6657 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6658 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
6659 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6660 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
6662 uni20::lapack::stevr(jobz, range, order, diagonal.data(), e,
Scalar{},
Scalar{}, first, last,
Scalar{},
6663 selected_count, result.
eigenvalues.data(), eigenvectors.
data(), ldz, support.
data(), work.data(),
6664 lwork, iwork.data(), liwork);
6666 if (selected_count < 0 ||
static_cast<std::size_t
>(selected_count) != selected)
6668 throw std::runtime_error(
"LAPACK stevr returned an unexpected number of eigenvalues");
6684template <uni20::LapackReal Scalar>
6686 std::vector<std::size_t>
const& selected_blocks)
6690 throw std::invalid_argument(
"real_schur_selected_subspace requires a square Schur form");
6693 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
schur_form.rows());
6695 if (n == 0 || selected_blocks.empty())
6702 throw std::invalid_argument(
"real_schur_selected_subspace received inconsistent Schur eigenvalue data");
6705 if (update_vectors && (!std::cmp_equal(decomposition.
schur_vectors.rows(), n) ||
6708 throw std::invalid_argument(
"real_schur_selected_subspace received inconsistent Schur vectors");
6710 if (decomposition.
blocks.empty())
6715 std::vector<bool> seen_blocks(decomposition.
blocks.size(),
false);
6716 std::vector<blas_int> select(n, 0);
6717 std::size_t expected_selected_dimension = 0;
6718 for (std::size_t
const block_index : selected_blocks)
6720 if (block_index >= decomposition.
blocks.size())
6722 throw std::invalid_argument(
"real_schur_selected_subspace received an out-of-range selected block index");
6724 if (seen_blocks[block_index])
6726 throw std::invalid_argument(
"real_schur_selected_subspace received a duplicate selected block index");
6728 seen_blocks[block_index] =
true;
6729 auto const& block = decomposition.
blocks[block_index];
6730 if (block.begin + block.size > n)
6732 throw std::invalid_argument(
"real_schur_selected_subspace received inconsistent Schur block metadata");
6734 for (std::size_t offset = 0; offset < block.size; ++offset)
6736 select[block.begin + offset] = 1;
6738 expected_selected_dimension += block.size;
6744 blas_int
const order = detail::checked_blas_int(n);
6745 blas_int
const ldq = update_vectors ? order : 1;
6746 char const job =
'B';
6747 char const compq = update_vectors ?
'V' :
'N';
6748 std::vector<Scalar> wr(n,
Scalar{});
6749 std::vector<Scalar> wi(n,
Scalar{});
6750 blas_int selected_dimension = 0;
6751 Scalar reciprocal_eigenvalue_cluster_condition{};
6752 Scalar reciprocal_invariant_subspace_condition{};
6755 blas_int iwork_query = 0;
6756 blas_int
const query_workspace = -1;
6758 wi.data(), selected_dimension, reciprocal_eigenvalue_cluster_condition,
6759 reciprocal_invariant_subspace_condition, &work_query, query_workspace, &iwork_query,
6762 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
6763 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
6764 std::vector<Scalar> work(
static_cast<std::size_t
>(lwork),
Scalar{});
6765 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
6767 wi.data(), selected_dimension, reciprocal_eigenvalue_cluster_condition,
6768 reciprocal_invariant_subspace_condition, work.data(), lwork, iwork.data(), liwork);
6770 if (selected_dimension < 0 ||
static_cast<std::size_t
>(selected_dimension) != expected_selected_dimension)
6772 throw std::runtime_error(
"LAPACK trsen returned an unexpected selected subspace dimension");
6775 decomposition.
schur_form = std::move(schur_form);
6780 for (std::size_t index = 0; index < n; ++index)
6801template <uni20::LapackReal Scalar>
6806 throw std::invalid_argument(
"real_schur_right_eigenvectors requires a square Schur form");
6809 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
schur_form.rows());
6818 throw std::invalid_argument(
"real_schur_right_eigenvectors received inconsistent Schur eigenvalue data");
6824 std::vector<blas_int> select(n, 1);
6825 std::vector<Scalar> work(3 * n,
Scalar{});
6826 blas_int
const order = detail::checked_blas_int(n);
6827 blas_int computed_vectors = 0;
6828 char const side =
'R';
6829 char const howmny =
'A';
6831 right_vectors.
data(), order, order, computed_vectors, work.data());
6833 if (computed_vectors < 0 ||
static_cast<std::size_t
>(computed_vectors) != n)
6835 throw std::runtime_error(
"LAPACK trevc returned an unexpected number of eigenvectors");
6838 for (std::size_t col = 0; col < n;)
6840 auto const eigenvalue = decomposition.
eigenvalues[col];
6841 if (eigenvalue.imag() ==
Scalar{})
6843 for (std::size_t
row = 0;
row < n; ++
row)
6853 throw std::runtime_error(
"LAPACK trevc returned an incomplete complex eigenvector pair");
6855 auto const next_eigenvalue = decomposition.
eigenvalues[col + 1];
6860 throw std::runtime_error(
"LAPACK trevc returned a non-adjacent complex eigenvector pair");
6863 for (std::size_t
row = 0;
row < n; ++
row)
6866 if (eigenvalue.imag() >
Scalar{})
6891template <uni20::LapackReal Scalar>
6896 throw std::invalid_argument(
"real_schur_condition_estimates requires a square Schur form");
6899 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
schur_form.rows());
6909 throw std::invalid_argument(
"real_schur_condition_estimates received inconsistent Schur eigenvalue data");
6915 std::vector<blas_int> select(n, 1);
6916 std::vector<Scalar> trevc_work(3 * n,
Scalar{});
6917 blas_int
const order = detail::checked_blas_int(n);
6918 blas_int computed_vectors = 0;
6920 right_vectors.
data(), order, order, computed_vectors, trevc_work.data());
6922 if (computed_vectors < 0 ||
static_cast<std::size_t
>(computed_vectors) != n)
6924 throw std::runtime_error(
"LAPACK trevc returned an unexpected number of Schur eigenvectors");
6927 blas_int computed_estimates = 0;
6928 blas_int
const ldwork = order;
6929 std::vector<Scalar> work(n * (n + 6),
Scalar{});
6930 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order - 2)), 0);
6934 ldwork, iwork.data());
6936 if (computed_estimates < 0 ||
static_cast<std::size_t
>(computed_estimates) != n)
6938 throw std::runtime_error(
"LAPACK trsna returned an unexpected number of condition estimates");
6956template <uni20::LapackReal Real>
6957RealNonsymmetricBalance<Real>
6961 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
6963 throw std::invalid_argument(
"real_nonsymmetric_balance requires a square matrix");
6966 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
6969 result.
scale.resize(n);
6976 blas_int
const order = detail::checked_blas_int(n);
6980 result.
scale.data());
6982 if (first <= 0 || last < first || last > order)
6984 throw std::runtime_error(
"LAPACK gebal returned an invalid balanced block interval");
7000template <uni20::LapackReal Real>
7001detail::ColumnMajorLapackMatrix<Real>
7006 std::size_t
const n = balance.
scale.size();
7007 if (!std::cmp_equal(vectors.
rows(), n))
7009 throw std::invalid_argument(
"real_nonsymmetric_balance_backtransform_right_vectors received incompatible vectors");
7013 throw std::invalid_argument(
"real_nonsymmetric_balance_backtransform_right_vectors received invalid balance data");
7015 if (n == 0 || vectors.
cols() == 0)
7020 blas_int
const order = detail::checked_blas_int(n);
7021 blas_int
const first = detail::checked_blas_int(balance.
balanced_first + 1);
7023 blas_int
const vector_count = detail::checked_blas_int(vectors.
cols());
7026 vectors.
data(), order);
7041template <uni20::LapackReal Real>
7042RealGeneralizedNonsymmetricBalance<Real>
7047 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
7049 throw std::invalid_argument(
"real_generalized_nonsymmetric_balance requires a square matrix");
7051 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
7053 throw std::invalid_argument(
"real_generalized_nonsymmetric_balance requires a square metric matrix");
7055 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
7057 throw std::invalid_argument(
"real_generalized_nonsymmetric_balance received incompatible matrix sizes");
7060 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
7072 blas_int
const order = detail::checked_blas_int(n);
7075 std::vector<Real> work(6 * n,
Real{});
7080 if (first <= 0 || last < first || last > order)
7082 throw std::runtime_error(
"LAPACK ggbal returned an invalid balanced block interval");
7098template <uni20::LapackReal Real>
7103 std::size_t
const n = balance.
left_scale.size();
7106 throw std::invalid_argument(
7107 "real_generalized_nonsymmetric_balance_backtransform_right_vectors received inconsistent balance data");
7109 if (!std::cmp_equal(vectors.
rows(), n))
7111 throw std::invalid_argument(
7112 "real_generalized_nonsymmetric_balance_backtransform_right_vectors received incompatible vectors");
7116 throw std::invalid_argument(
7117 "real_generalized_nonsymmetric_balance_backtransform_right_vectors received invalid balance data");
7119 if (n == 0 || vectors.
cols() == 0)
7124 blas_int
const order = detail::checked_blas_int(n);
7125 blas_int
const first = detail::checked_blas_int(balance.
balanced_first + 1);
7127 blas_int
const vector_count = detail::checked_blas_int(vectors.
cols());
7128 std::vector<Real> left_scale = balance.
left_scale;
7129 std::vector<Real> right_scale = balance.
right_scale;
7130 uni20::lapack::ggbak(detail::lapack_balance_job(job),
'R', order, first, last, left_scale.data(), right_scale.data(),
7131 vector_count, vectors.
data(), order);
7146template <uni20::LapackReal Real>
7147RealGeneralizedHessenbergReduction<Real>
7150 bool compute_vectors)
7152 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
7154 throw std::invalid_argument(
"real_generalized_hessenberg_reduction requires a square matrix");
7156 if (!std::cmp_equal(upper_triangular_metric.
rows(), upper_triangular_metric.
cols()))
7158 throw std::invalid_argument(
"real_generalized_hessenberg_reduction requires a square metric matrix");
7160 if (!std::cmp_equal(matrix.
rows(), upper_triangular_metric.
rows()))
7162 throw std::invalid_argument(
"real_generalized_hessenberg_reduction received incompatible matrix sizes");
7165 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
7166 for (std::size_t col = 0; col < n; ++col)
7168 for (std::size_t
row = col + 1;
row < n; ++
row)
7170 if (upper_triangular_metric[
row, col] !=
Real{})
7172 throw std::invalid_argument(
"real_generalized_hessenberg_reduction requires an upper-triangular metric");
7191 blas_int
const order = detail::checked_blas_int(n);
7192 blas_int
const first = 1;
7193 blas_int
const last = order;
7194 blas_int
const ldq = compute_vectors ? order : 1;
7195 blas_int
const ldz = compute_vectors ? order : 1;
7196 char const compq = compute_vectors ?
'I' :
'N';
7197 char const compz = compute_vectors ?
'I' :
'N';
7200 left_vectors.
data(), ldq, right_vectors.
data(), ldz);
7222template <uni20::LapackReal Real>
7223RealGeneralizedSchurDecomposition<Real>
7227 if (!std::cmp_equal(hessenberg.
rows(), hessenberg.
cols()))
7229 throw std::invalid_argument(
"real_generalized_hessenberg_schur requires a square Hessenberg matrix");
7231 if (!std::cmp_equal(upper_triangular_metric.
rows(), upper_triangular_metric.
cols()))
7233 throw std::invalid_argument(
"real_generalized_hessenberg_schur requires a square metric matrix");
7235 if (!std::cmp_equal(hessenberg.
rows(), upper_triangular_metric.
rows()))
7237 throw std::invalid_argument(
"real_generalized_hessenberg_schur received incompatible matrix sizes");
7240 std::size_t
const n =
static_cast<std::size_t
>(hessenberg.
rows());
7241 for (std::size_t col = 0; col < n; ++col)
7243 for (std::size_t
row = col + 2;
row < n; ++
row)
7245 if (hessenberg[
row, col] !=
Real{})
7247 throw std::invalid_argument(
"real_generalized_hessenberg_schur requires an upper-Hessenberg matrix");
7250 for (std::size_t
row = col + 1;
row < n; ++
row)
7252 if (upper_triangular_metric[
row, col] !=
Real{})
7254 throw std::invalid_argument(
"real_generalized_hessenberg_schur requires an upper-triangular metric");
7260 result.
alpha.resize(n);
7261 result.
beta.resize(n);
7272 blas_int
const order = detail::checked_blas_int(n);
7273 std::vector<Real> alphar(n,
Real{});
7274 std::vector<Real> alphai(n,
Real{});
7278 blas_int
const ldq = compute_vectors ? order : 1;
7279 blas_int
const ldz = compute_vectors ? order : 1;
7280 blas_int
const first = 1;
7281 blas_int
const last = order;
7282 char const job =
'S';
7283 char const compq = compute_vectors ?
'I' :
'N';
7284 char const compz = compute_vectors ?
'I' :
'N';
7287 blas_int
const query_lwork = -1;
7289 order, alphar.data(), alphai.data(),
beta.data(), left_vectors.data(), ldq, right_vectors.data(),
7290 ldz, &work_query, query_lwork);
7292 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
7293 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
7295 order, alphar.data(), alphai.data(),
beta.data(), left_vectors.data(), ldq, right_vectors.data(),
7296 ldz, work.data(), lwork);
7302 for (std::size_t i = 0; i < n; ++i)
7306 result.
eigenvalues[i] = detail::generalized_eigenvalue(alphar[i], alphai[i],
beta[i]);
7323template <uni20::LapackReal Real>
7326 bool compute_vectors)
7328 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
7330 throw std::invalid_argument(
"real_generalized_schur requires a square matrix");
7332 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
7334 throw std::invalid_argument(
"real_generalized_schur requires a square metric matrix");
7336 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
7338 throw std::invalid_argument(
"real_generalized_schur received incompatible matrix sizes");
7341 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
7343 result.
alpha.resize(n);
7344 result.
beta.resize(n);
7355 blas_int
const order = detail::checked_blas_int(n);
7356 std::vector<Real> alphar(n,
Real{});
7357 std::vector<Real> alphai(n,
Real{});
7361 blas_int
const ldvsl = compute_vectors ? order : 1;
7362 blas_int
const ldvsr = compute_vectors ? order : 1;
7363 char const jobvsl = compute_vectors ?
'V' :
'N';
7364 char const jobvsr = compute_vectors ?
'V' :
'N';
7365 char const sort =
'N';
7366 blas_int selected_dimension = 0;
7367 std::vector<blas_int> bwork(std::max<std::size_t>(1, n), 0);
7370 blas_int
const query_lwork = -1;
7372 alphar.data(), alphai.data(),
beta.data(), left_vectors.data(), ldvsl, right_vectors.data(),
7373 ldvsr, &work_query, query_lwork, bwork.data());
7375 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
7376 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
7378 alphar.data(), alphai.data(),
beta.data(), left_vectors.data(), ldvsl, right_vectors.data(),
7379 ldvsr, work.data(), lwork, bwork.data());
7386 for (std::size_t i = 0; i < n; ++i)
7390 result.
eigenvalues[i] = detail::generalized_eigenvalue(alphar[i], alphai[i],
beta[i]);
7406template <uni20::LapackReal Real>
7407RealGeneralizedSchurDecomposition<Real>
7409 std::vector<std::size_t>
const& leading_block_order)
7413 throw std::invalid_argument(
"reorder_real_generalized_schur requires a square matrix Schur form");
7417 throw std::invalid_argument(
"reorder_real_generalized_schur requires a square metric Schur form");
7420 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
matrix_schur_form.rows());
7421 if (n == 0 || leading_block_order.empty())
7423 return decomposition;
7429 throw std::invalid_argument(
"reorder_real_generalized_schur received inconsistent Schur form sizes");
7431 if (decomposition.
alpha.size() != n || decomposition.
beta.size() != n || decomposition.
eigenvalues.size() != n)
7433 throw std::invalid_argument(
"reorder_real_generalized_schur received inconsistent eigenvalue data");
7435 bool const has_left_vectors =
7437 bool const has_right_vectors =
7439 if (has_left_vectors != has_right_vectors)
7441 throw std::invalid_argument(
"reorder_real_generalized_schur requires both Schur vector sets or neither");
7443 bool const update_vectors = has_left_vectors;
7444 if (update_vectors && (!std::cmp_equal(decomposition.
left_schur_vectors.rows(), n) ||
7449 throw std::invalid_argument(
"reorder_real_generalized_schur received inconsistent Schur vectors");
7452 std::vector<std::size_t> target_order =
7453 detail::complete_leading_block_order(decomposition.
blocks.size(), leading_block_order);
7454 std::vector<std::size_t> current_order(decomposition.
blocks.size());
7455 std::iota(current_order.begin(), current_order.end(), std::size_t{0});
7456 std::vector<RealSchurBlock<Real>> current_blocks = decomposition.
blocks;
7458 blas_int
const order = detail::checked_blas_int(n);
7459 blas_int
const ldq = update_vectors ? order : 1;
7460 blas_int
const ldz = update_vectors ? order : 1;
7465 blas_int
const lwork = std::max<blas_int>(1, 4 * order + 16);
7466 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
7468 for (std::size_t target_position = 0; target_position < leading_block_order.size(); ++target_position)
7470 std::size_t
const desired_original_index = target_order[target_position];
7471 auto const current_it = std::ranges::find(current_order, desired_original_index);
7472 if (current_it == current_order.end())
7474 throw std::logic_error(
"generalized real Schur block reorder lost a block index");
7476 std::size_t
const current_position =
static_cast<std::size_t
>(current_it - current_order.begin());
7477 if (current_position == target_position)
7482 blas_int first = detail::checked_blas_int(current_blocks[current_position].
begin + 1);
7483 blas_int last = detail::checked_blas_int(current_blocks[target_position].
begin + 1);
7486 ldz, first, last, work.data(), lwork);
7488 std::size_t
const moved_index = current_order[current_position];
7489 current_order.erase(current_order.begin() +
static_cast<std::ptrdiff_t
>(current_position));
7490 current_order.insert(current_order.begin() +
static_cast<std::ptrdiff_t
>(target_position), moved_index);
7491 current_blocks = detail::ordered_schur_blocks(decomposition.
blocks, current_order);
7498 decomposition.
alpha = detail::ordered_schur_block_values(decomposition.
alpha, decomposition.
blocks, current_order);
7499 decomposition.
beta = detail::ordered_schur_block_values(decomposition.
beta, decomposition.
blocks, current_order);
7500 decomposition.
blocks = detail::ordered_schur_blocks(decomposition.
blocks, current_order);
7501 decomposition.
eigenvalues = detail::eigenvalues_from_schur_blocks(decomposition.
blocks);
7502 return decomposition;
7514template <uni20::LapackReal Real>
7515RealGeneralizedSchurSelectedSubspace<Real>
7517 std::vector<std::size_t>
const& selected_blocks)
7521 throw std::invalid_argument(
"real_generalized_schur_selected_subspace requires a square matrix Schur form");
7525 throw std::invalid_argument(
"real_generalized_schur_selected_subspace requires a square metric Schur form");
7528 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
matrix_schur_form.rows());
7530 if (n == 0 || selected_blocks.empty())
7539 throw std::invalid_argument(
"real_generalized_schur_selected_subspace received inconsistent Schur form sizes");
7541 if (decomposition.
alpha.size() != n || decomposition.
beta.size() != n || decomposition.
eigenvalues.size() != n)
7543 throw std::invalid_argument(
"real_generalized_schur_selected_subspace received inconsistent eigenvalue data");
7545 bool const has_left_vectors =
7547 bool const has_right_vectors =
7549 if (has_left_vectors != has_right_vectors)
7551 throw std::invalid_argument(
"real_generalized_schur_selected_subspace requires both Schur vector sets or neither");
7553 bool const update_vectors = has_left_vectors;
7554 if (update_vectors && (!std::cmp_equal(decomposition.
left_schur_vectors.rows(), n) ||
7559 throw std::invalid_argument(
"real_generalized_schur_selected_subspace received inconsistent Schur vectors");
7561 if (decomposition.
blocks.empty())
7566 std::vector<bool> seen_blocks(decomposition.
blocks.size(),
false);
7567 std::vector<blas_int> select(n, 0);
7568 std::size_t expected_selected_dimension = 0;
7569 for (std::size_t
const block_index : selected_blocks)
7571 if (block_index >= decomposition.
blocks.size())
7573 throw std::invalid_argument(
"real_generalized_schur_selected_subspace received an out-of-range selected block");
7575 if (seen_blocks[block_index])
7577 throw std::invalid_argument(
"real_generalized_schur_selected_subspace received a duplicate selected block");
7579 seen_blocks[block_index] =
true;
7580 auto const& block = decomposition.
blocks[block_index];
7581 if (block.begin + block.size > n)
7583 throw std::invalid_argument(
"real_generalized_schur_selected_subspace received inconsistent block metadata");
7585 for (std::size_t offset = 0; offset < block.size; ++offset)
7587 select[block.begin + offset] = 1;
7589 expected_selected_dimension += block.size;
7598 std::vector<Real> alphar(n,
Real{});
7599 std::vector<Real> alphai(n,
Real{});
7601 std::array<Real, 2> dif{
Real{},
Real{}};
7602 blas_int
const order = detail::checked_blas_int(n);
7603 blas_int
const ldq = update_vectors ? order : 1;
7604 blas_int
const ldz = update_vectors ? order : 1;
7605 blas_int
const ijob = 4;
7606 blas_int selected_dimension = 0;
7611 blas_int iwork_query = 0;
7612 blas_int
const query_workspace = -1;
7614 metric_schur_form.
data(), order, alphar.data(), alphai.data(),
beta.data(), left_vectors.
data(),
7615 ldq, right_vectors.
data(), ldz, selected_dimension, pl, pr, dif.data(), &work_query,
7616 query_workspace, &iwork_query, query_workspace);
7618 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
7619 blas_int
const liwork = std::max<blas_int>(1, iwork_query);
7620 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
7621 std::vector<blas_int> iwork(
static_cast<std::size_t
>(liwork), 0);
7623 metric_schur_form.
data(), order, alphar.data(), alphai.data(),
beta.data(), left_vectors.
data(),
7624 ldq, right_vectors.
data(), ldz, selected_dimension, pl, pr, dif.data(), work.data(), lwork,
7625 iwork.data(), liwork);
7627 if (selected_dimension < 0 ||
static_cast<std::size_t
>(selected_dimension) != expected_selected_dimension)
7629 throw std::runtime_error(
"LAPACK tgsen returned an unexpected selected subspace dimension");
7638 for (std::size_t i = 0; i < n; ++i)
7642 decomposition.
eigenvalues[i] = detail::generalized_eigenvalue(alphar[i], alphai[i],
beta[i]);
7663template <uni20::LapackReal Real>
7664RealGeneralizedSchurRightEigenvectors<Real>
7669 throw std::invalid_argument(
"real_generalized_schur_right_eigenvectors requires a square matrix Schur form");
7673 throw std::invalid_argument(
"real_generalized_schur_right_eigenvectors requires a square metric Schur form");
7676 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
matrix_schur_form.rows());
7687 throw std::invalid_argument(
"real_generalized_schur_right_eigenvectors received inconsistent Schur form sizes");
7691 throw std::invalid_argument(
"real_generalized_schur_right_eigenvectors received inconsistent eigenvalue data");
7698 std::vector<blas_int> select(n, 1);
7699 std::vector<Real> work(6 * n,
Real{});
7700 blas_int
const order = detail::checked_blas_int(n);
7701 blas_int computed_vectors = 0;
7702 char const side =
'R';
7703 char const howmny =
'A';
7705 order, left_vectors.
data(), 1, right_vectors.
data(), order, order, computed_vectors,
7708 if (computed_vectors < 0 ||
static_cast<std::size_t
>(computed_vectors) != n)
7710 throw std::runtime_error(
"LAPACK tgevc returned an unexpected number of generalized Schur eigenvectors");
7713 for (std::size_t col = 0; col < n;)
7715 auto const eigenvalue = decomposition.
eigenvalues[col];
7716 if (eigenvalue.imag() ==
Real{})
7718 for (std::size_t
row = 0;
row < n; ++
row)
7728 throw std::runtime_error(
"LAPACK tgevc returned an incomplete complex eigenvector pair");
7730 auto const next_eigenvalue = decomposition.
eigenvalues[col + 1];
7735 throw std::runtime_error(
"LAPACK tgevc returned a non-adjacent complex eigenvector pair");
7738 for (std::size_t
row = 0;
row < n; ++
row)
7741 if (eigenvalue.imag() >
Real{})
7766template <uni20::LapackReal Real>
7767RealGeneralizedSchurConditionEstimates<Real>
7772 throw std::invalid_argument(
"real_generalized_schur_condition_estimates requires a square matrix Schur form");
7776 throw std::invalid_argument(
"real_generalized_schur_condition_estimates requires a square metric Schur form");
7779 std::size_t
const n =
static_cast<std::size_t
>(decomposition.
matrix_schur_form.rows());
7791 throw std::invalid_argument(
"real_generalized_schur_condition_estimates received inconsistent Schur form sizes");
7795 throw std::invalid_argument(
"real_generalized_schur_condition_estimates received inconsistent eigenvalue data");
7802 std::vector<blas_int> select(n, 1);
7803 std::vector<Real> tgevc_work(6 * n,
Real{});
7804 blas_int
const order = detail::checked_blas_int(n);
7805 blas_int computed_vectors = 0;
7807 left_vectors.
data(), order, right_vectors.
data(), order, order, computed_vectors,
7810 if (computed_vectors < 0 ||
static_cast<std::size_t
>(computed_vectors) != n)
7812 throw std::runtime_error(
"LAPACK tgevc returned an unexpected number of generalized Schur eigenvectors");
7815 blas_int computed_estimates = 0;
7816 blas_int
const lwork = std::max<blas_int>(1, 2 * order * (order + 2) + 16);
7817 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
7818 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order + 6)), 0);
7820 left_vectors.
data(), order, right_vectors.
data(), order,
7823 lwork, iwork.data());
7825 if (computed_estimates < 0 ||
static_cast<std::size_t
>(computed_estimates) != n)
7827 throw std::runtime_error(
"LAPACK tgsna returned an unexpected number of condition estimates");
7846template <uni20::LapackReal Real>
7847RealNonsymmetricExpertEigensystem<Real>
7850 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
7852 throw std::invalid_argument(
"real_nonsymmetric_expert_eigensystem requires a square matrix");
7855 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
7859 compute_right_vectors ? n : 0);
7868 blas_int
const order = detail::checked_blas_int(n);
7869 std::vector<Real> wr(n,
Real{});
7870 std::vector<Real> wi(n,
Real{});
7873 blas_int
const ldvl = order;
7874 blas_int
const ldvr = order;
7875 char const balanc =
'B';
7876 char const jobvl =
'V';
7877 char const jobvr =
'V';
7878 char const sense =
'B';
7881 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, 2 * order - 2)), 0);
7884 blas_int
const query_lwork = -1;
7885 uni20::lapack::geevx(balanc, jobvl, jobvr, sense, order, matrix.
data(), order, wr.data(), wi.data(), vl.data(), ldvl,
7890 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
7891 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
7892 uni20::lapack::geevx(balanc, jobvl, jobvr, sense, order, matrix.
data(), order, wr.data(), wi.data(), vl.data(), ldvl,
7897 if (ilo <= 0 || ihi < ilo || ihi > order)
7899 throw std::runtime_error(
"LAPACK geevx returned an invalid balanced block interval");
7904 for (std::size_t i = 0; i < n; ++i)
7909 if (!compute_right_vectors)
7914 for (std::size_t col = 0; col < n; ++col)
7916 if (wi[col] ==
Real{})
7918 for (std::size_t
row = 0;
row < n; ++
row)
7923 else if (wi[col] >
Real{})
7927 throw std::runtime_error(
"LAPACK geevx returned an incomplete complex conjugate eigenvector pair");
7929 for (std::size_t
row = 0;
row < n; ++
row)
7956template <uni20::LapackReal Real>
7957RealGeneralizedNonsymmetricEigensystem<Real>
7961 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
7963 throw std::invalid_argument(
"real_generalized_nonsymmetric_eigensystem requires a square matrix");
7965 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
7967 throw std::invalid_argument(
"real_generalized_nonsymmetric_eigensystem requires a square metric matrix");
7969 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
7971 throw std::invalid_argument(
"real_generalized_nonsymmetric_eigensystem received incompatible matrix sizes");
7974 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
7976 result.
alpha.resize(n);
7977 result.
beta.resize(n);
7980 compute_right_vectors ? n : 0);
7986 blas_int
const order = detail::checked_blas_int(n);
7987 std::vector<Real> alphar(n,
Real{});
7988 std::vector<Real> alphai(n,
Real{});
7990 std::vector<Real> vl(1,
Real{});
7992 blas_int
const ldvl = 1;
7993 blas_int
const ldvr = compute_right_vectors ? order : 1;
7994 char const jobvl =
'N';
7995 char const jobvr = compute_right_vectors ?
'V' :
'N';
7998 blas_int
const query_lwork = -1;
8000 beta.data(), vl.data(), ldvl, vr.data(), ldvr, &work_query, query_lwork);
8002 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
8003 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
8005 beta.data(), vl.data(), ldvl, vr.data(), ldvr, work.data(), lwork);
8007 for (std::size_t i = 0; i < n; ++i)
8011 result.
eigenvalues[i] = detail::generalized_eigenvalue(alphar[i], alphai[i],
beta[i]);
8014 if (!compute_right_vectors)
8019 for (std::size_t col = 0; col < n; ++col)
8021 if (alphai[col] ==
Real{})
8023 for (std::size_t
row = 0;
row < n; ++
row)
8028 else if (alphai[col] >
Real{})
8032 throw std::runtime_error(
"LAPACK ggev returned an incomplete complex conjugate eigenvector pair");
8034 for (std::size_t
row = 0;
row < n; ++
row)
8062template <uni20::LapackReal Real>
8063RealGeneralizedNonsymmetricExpertEigensystem<Real>
8066 bool compute_right_vectors)
8068 if (!std::cmp_equal(matrix.
rows(), matrix.
cols()))
8070 throw std::invalid_argument(
"real_generalized_nonsymmetric_expert_eigensystem requires a square matrix");
8072 if (!std::cmp_equal(metric.
rows(), metric.
cols()))
8074 throw std::invalid_argument(
"real_generalized_nonsymmetric_expert_eigensystem requires a square metric matrix");
8076 if (!std::cmp_equal(matrix.
rows(), metric.
rows()))
8078 throw std::invalid_argument(
"real_generalized_nonsymmetric_expert_eigensystem received incompatible matrix sizes");
8081 std::size_t
const n =
static_cast<std::size_t
>(matrix.
rows());
8083 result.
alpha.resize(n);
8084 result.
beta.resize(n);
8087 compute_right_vectors ? n : 0);
8097 blas_int
const order = detail::checked_blas_int(n);
8098 std::vector<Real> alphar(n,
Real{});
8099 std::vector<Real> alphai(n,
Real{});
8103 blas_int
const ldvl = order;
8104 blas_int
const ldvr = order;
8105 char const balanc =
'B';
8106 char const jobvl =
'V';
8107 char const jobvr =
'V';
8108 char const sense =
'B';
8111 std::vector<blas_int> iwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order + 6)), 0);
8112 std::vector<blas_int> bwork(
static_cast<std::size_t
>(std::max<blas_int>(1, order)), 0);
8115 blas_int
const query_lwork = -1;
8116 uni20::lapack::ggevx(balanc, jobvl, jobvr, sense, order, matrix.
data(), order, metric.
data(), order, alphar.data(),
8117 alphai.data(),
beta.data(), vl.data(), ldvl, vr.
data(), ldvr, ilo, ihi,
8123 blas_int
const lwork = std::max<blas_int>(1,
static_cast<blas_int
>(work_query));
8124 std::vector<Real> work(
static_cast<std::size_t
>(lwork),
Real{});
8125 uni20::lapack::ggevx(balanc, jobvl, jobvr, sense, order, matrix.
data(), order, metric.
data(), order, alphar.data(),
8126 alphai.data(),
beta.data(), vl.data(), ldvl, vr.
data(), ldvr, ilo, ihi,
8132 if (ilo <= 0 || ihi < ilo || ihi > order)
8134 throw std::runtime_error(
"LAPACK ggevx returned an invalid balanced block interval");
8139 for (std::size_t i = 0; i < n; ++i)
8143 result.
eigenvalues[i] = detail::generalized_eigenvalue(alphar[i], alphai[i],
beta[i]);
8146 if (!compute_right_vectors)
8151 for (std::size_t col = 0; col < n; ++col)
8153 if (alphai[col] ==
Real{})
8155 for (std::size_t
row = 0;
row < n; ++
row)
8160 else if (alphai[col] >
Real{})
8164 throw std::runtime_error(
"LAPACK ggevx returned an incomplete complex conjugate eigenvector pair");
8166 for (std::size_t
row = 0;
row < n; ++
row)
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
auto rows() const noexcept
Return the matrix row count for rank-two tensors.
Definition basic_tensor.hpp:768
auto data() noexcept -> element_type *requires(immediately_writable &&(std::same_as< layout_type, stdex::layout_left >||std::same_as< layout_type, stdex::layout_right >) &&is_default_accessor_v< accessor_type > &&std::same_as< mutable_handle_type, element_type * >)
Return contiguous mutable element storage for a canonical tensor.
Definition basic_tensor.hpp:684
auto size() const noexcept -> size_type
Return the number of elements in the mapped storage span.
Definition basic_tensor.hpp:756
auto cols() const noexcept
Return the matrix column count for rank-two tensors.
Definition basic_tensor.hpp:776
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
Concept for real scalar types (float, double, etc.).
Definition scalar_concepts.hpp:69
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
locale_t value
Definition data_table.cpp:49
typename detail::complex_type< Real >::type complex
Project-level complex scalar spelling.
Definition types.hpp:66
int rows(std::FILE *stream)
Return the terminal row count associated with a C stream.
Definition terminal.cpp:482
Definition block_tensor_vector.hpp:23
Scalar real_matrix_norm(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixNorm norm)
Definition dense_subspace_unused.hpp:738
RealGeneralizedSchurSelectedSubspace< Real > real_generalized_schur_selected_subspace(RealGeneralizedSchurDecomposition< Real > decomposition, std::vector< std::size_t > const &selected_blocks)
Move selected generalized real Schur blocks to the leading deflating subspace and estimate conditioni...
Definition dense_subspace_unused.hpp:7516
detail::ColumnMajorLapackMatrix< Scalar > real_bidiagonal_right_orthogonal_factor_transpose(RealBidiagonalReduction< Scalar > const &reduction)
Materialize the right transposed factor P^T from a real bidiagonal reduction.
Definition dense_subspace_unused.hpp:5790
ComplexHermitianEigensystem< Real > complex_hermitian_eigensystem(detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > matrix, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense complex Hermitian eigensystem through LAPACK heev.
Definition dense_subspace_unused.hpp:4478
detail::ColumnMajorLapackMatrix< Scalar > real_dense_solve_linear_system(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a dense real linear system through LAPACK gesv.
Definition dense_subspace_unused.hpp:2576
detail::ColumnMajorLapackMatrix< Scalar > apply_real_bidiagonal_left_factor(RealBidiagonalReduction< Scalar > const &reduction, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Left, MatrixTranspose transpose=MatrixTranspose::None)
Apply the left orthogonal factor Q from a real bidiagonal reduction.
Definition dense_subspace_unused.hpp:5842
RealGeneralizedSchurDecomposition< Real > real_generalized_hessenberg_schur(detail::ColumnMajorLapackMatrix< Real > hessenberg, detail::ColumnMajorLapackMatrix< Real > upper_triangular_metric, bool compute_vectors)
Compute generalized real Schur form from a generalized Hessenberg pencil through LAPACK hgeqz.
Definition dense_subspace_unused.hpp:7224
RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > real_symmetric_positive_definite_tridiagonal_from_dense(detail::ColumnMajorLapackMatrix< Scalar > const &matrix)
Extract real SPD tridiagonal storage from a dense matrix.
Definition dense_subspace_unused.hpp:2198
RealCompactQrFactorization< Scalar > real_compact_qr_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a compact dense real QR factorization through LAPACK geqrf.
Definition dense_subspace_unused.hpp:4844
RealHessenbergReduction< Scalar > real_hessenberg_reduction(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Reduce a dense real square matrix to upper Hessenberg form through LAPACK gehrd.
Definition dense_subspace_unused.hpp:5960
RealGeneralizedNonsymmetricEigensystem< Real > real_generalized_nonsymmetric_eigensystem(detail::ColumnMajorLapackMatrix< Real > matrix, detail::ColumnMajorLapackMatrix< Real > metric, bool compute_right_vectors)
Solve a dense real generalized nonsymmetric eigensystem through LAPACK ggev.
Definition dense_subspace_unused.hpp:7958
Scalar real_general_tridiagonal_one_norm(RealGeneralTridiagonalMatrix< Scalar > const &matrix)
Compute the one-norm of a real general tridiagonal matrix.
Definition dense_subspace_unused.hpp:1182
RealGeneralizedSchurConditionEstimates< Real > real_generalized_schur_condition_estimates(RealGeneralizedSchurDecomposition< Real > decomposition)
Estimate generalized Schur eigenvalue and eigenvector conditioning through LAPACK tgsna.
Definition dense_subspace_unused.hpp:7768
detail::ColumnMajorLapackMatrix< Scalar > real_triangular_inverse(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper, bool unit_diagonal=false)
Invert a dense real triangular matrix through LAPACK trtri.
Definition dense_subspace_unused.hpp:2958
Scalar real_symmetric_indefinite_one_norm_reciprocal_condition_number(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Estimate a dense real symmetric-indefinite one-norm reciprocal condition number through LAPACK sycon.
Definition dense_subspace_unused.hpp:4029
RealRefinedLinearSolve< Scalar > real_symmetric_positive_definite_tridiagonal_refined_solve(RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve and refine a real SPD tridiagonal linear system through LAPACK ptrfs.
Definition dense_subspace_unused.hpp:2412
RealSymmetricEigensystem< Scalar > real_symmetric_eigensystem(detail::ColumnMajorLapackMatrix< Scalar > matrix, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense real symmetric eigensystem through LAPACK syev.
Definition dense_subspace_unused.hpp:4117
TridiagonalEigensystem< Scalar > symmetric_tridiagonal_eigensystem_divide_and_conquer(std::vector< Scalar > diagonal, std::vector< Scalar > subdiagonal, bool compute_vectors)
Solve a real symmetric tridiagonal eigenvalue problem through LAPACK sterf.
Definition dense_subspace_unused.hpp:6563
RealGeneralTridiagonalFactorization< Scalar > real_general_tridiagonal_factorization(RealGeneralTridiagonalMatrix< Scalar > matrix)
Compute a real general tridiagonal LU factorization through LAPACK gttrf.
Definition dense_subspace_unused.hpp:1079
RealGeneralizedSchurRightEigenvectors< Real > real_generalized_schur_right_eigenvectors(RealGeneralizedSchurDecomposition< Real > decomposition)
Compute right eigenvectors of a generalized real Schur form through LAPACK tgevc.
Definition dense_subspace_unused.hpp:7665
RealQrFactorization< Scalar > real_qr_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a reduced dense real QR factorization through LAPACK geqrf and orgqr.
Definition dense_subspace_unused.hpp:4944
RealCompactLqFactorization< Scalar > real_compact_lq_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a compact dense real LQ factorization through LAPACK gelqf.
Definition dense_subspace_unused.hpp:4999
RealRefinedLinearSolve< Scalar > real_general_band_refined_solve(RealGeneralBandMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixTranspose transpose=MatrixTranspose::None)
Solve and refine a real general-band system through LAPACK gbrfs.
Definition dense_subspace_unused.hpp:1513
detail::ColumnMajorLapackMatrix< Scalar > real_general_band_solve(RealGeneralBandMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a real general-band linear system through LAPACK gbsv.
Definition dense_subspace_unused.hpp:884
RealSymmetricPositiveDefiniteBandExpertLinearSolve< Scalar > real_symmetric_positive_definite_band_expert_linear_solve(RealSymmetricPositiveDefiniteBandMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a real SPD band linear system with LAPACK pbsvx diagnostics.
Definition dense_subspace_unused.hpp:2138
RealSymmetricEigensystem< Scalar > real_generalized_symmetric_eigensystem(detail::ColumnMajorLapackMatrix< Scalar > matrix, detail::ColumnMajorLapackMatrix< Scalar > metric, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense type-1 generalized real symmetric eigensystem through LAPACK sygv.
Definition dense_subspace_unused.hpp:4282
detail::ColumnMajorLapackMatrix< Scalar > real_least_squares(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a dense real least-squares or minimum-norm problem through LAPACK gels.
Definition dense_subspace_unused.hpp:3130
void laset(uni20::DenseMatrix< Scalar > &matrix, Scalar const &diagonal, Scalar const &off_diagonal, MatrixFill fill)
Set a selected region of a local dense matrix.
Definition dense_linalg.hpp:294
detail::ColumnMajorLapackMatrix< Scalar > real_lu_solve(RealLuFactorization< Scalar > const &factorization, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixTranspose transpose=MatrixTranspose::None)
Solve using an existing dense real LU factorization through LAPACK getrs.
Definition dense_subspace_unused.hpp:2713
detail::ColumnMajorLapackMatrix< Scalar > real_dense_inverse(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Invert a dense real square matrix through LAPACK getrf and getri.
Definition dense_subspace_unused.hpp:3093
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_indefinite_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper)
Solve a dense real symmetric indefinite system through LAPACK sytrf and sytrs.
Definition dense_subspace_unused.hpp:3778
RealSvdLeastSquares< Scalar > real_divide_and_conquer_svd_least_squares(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, Scalar rcond=Scalar{100} *uni20::numeric_limits< Scalar >::epsilon())
Solve a dense real divide-and-conquer SVD least-squares problem through LAPACK gelsd.
Definition dense_subspace_unused.hpp:3277
Scalar real_one_norm_reciprocal_condition_number(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Estimate the one-norm reciprocal condition number of a dense real matrix.
Definition dense_subspace_unused.hpp:2846
RealLuFactorization< Scalar > real_lu_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a dense real LU factorization through LAPACK getrf.
Definition dense_subspace_unused.hpp:2673
RealSymmetricEigensystem< Scalar > real_generalized_symmetric_eigensystem_index_range(detail::ColumnMajorLapackMatrix< Scalar > matrix, detail::ColumnMajorLapackMatrix< Scalar > metric, std::size_t first_index, std::size_t last_index, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a selected dense type-1 generalized real symmetric eigensystem through LAPACK sygvx.
Definition dense_subspace_unused.hpp:4405
RealSymmetricPositiveDefiniteBandMatrix< Scalar > real_symmetric_positive_definite_band_from_dense(detail::ColumnMajorLapackMatrix< Scalar > const &matrix, std::size_t bandwidth, MatrixFill triangle=MatrixFill::Upper)
Pack a dense real SPD matrix into LAPACK symmetric-band storage.
Definition dense_subspace_unused.hpp:1812
RealNonsymmetricExpertEigensystem< Real > real_nonsymmetric_expert_eigensystem(detail::ColumnMajorLapackMatrix< Real > matrix, bool compute_right_vectors)
Solve a dense real nonsymmetric eigensystem through LAPACK geev.
Definition dense_subspace_unused.hpp:7848
detail::ColumnMajorLapackMatrix< Real > real_nonsymmetric_balance_backtransform_right_vectors(detail::ColumnMajorLapackMatrix< Real > vectors, RealNonsymmetricBalance< Real > const &balance, RealNonsymmetricBalanceJob job=RealNonsymmetricBalanceJob::Both)
Backtransform real right eigenvectors after real_nonsymmetric_balance.
Definition dense_subspace_unused.hpp:7002
Scalar real_symmetric_matrix_norm(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixNorm norm, MatrixFill triangle=MatrixFill::Upper)
Compute a dense real symmetric matrix norm through LAPACK lansy.
Definition dense_subspace_unused.hpp:760
RealBidiagonalSvd< Scalar > real_bidiagonal_svd(std::vector< Scalar > diagonal, std::vector< Scalar > offdiagonal, bool compute_vectors, bool upper=true)
Compute the SVD of a real bidiagonal matrix through LAPACK bdsdc.
Definition dense_subspace_unused.hpp:5588
RealGeneralizedSchurDecomposition< Real > real_generalized_schur(detail::ColumnMajorLapackMatrix< Real > matrix, detail::ColumnMajorLapackMatrix< Real > metric, bool compute_vectors)
Compute the generalized real Schur decomposition of a matrix pencil through LAPACK gges.
Definition dense_subspace_unused.hpp:7324
RealGeneralBandExpertLinearSolve< Scalar > real_general_band_expert_linear_solve(RealGeneralBandMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixTranspose transpose=MatrixTranspose::None)
Solve a real general-band linear system with LAPACK gbsvx diagnostics.
Definition dense_subspace_unused.hpp:1582
RealSymmetricPositiveDefiniteBandFactorization< Scalar > real_symmetric_positive_definite_band_factorization(RealSymmetricPositiveDefiniteBandMatrix< Scalar > matrix)
Compute a real SPD band Cholesky factorization through LAPACK pbtrf.
Definition dense_subspace_unused.hpp:1895
RealRqFactorization< Scalar > real_rq_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a reduced dense real RQ factorization through LAPACK gerqf and orgrq.
Definition dense_subspace_unused.hpp:5413
RealGeneralizedNonsymmetricExpertEigensystem< Real > real_generalized_nonsymmetric_expert_eigensystem(detail::ColumnMajorLapackMatrix< Real > matrix, detail::ColumnMajorLapackMatrix< Real > metric, bool compute_right_vectors)
Solve a dense real generalized nonsymmetric eigensystem through LAPACK ggevx.
Definition dense_subspace_unused.hpp:8064
RealSymmetricPositiveDefiniteExpertLinearSolve< Scalar > real_symmetric_positive_definite_expert_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper)
Solve a dense real SPD linear system with LAPACK posvx diagnostics.
Definition dense_subspace_unused.hpp:3573
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_positive_definite_tridiagonal_solve(RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a real SPD tridiagonal system through LAPACK ptsv.
Definition dense_subspace_unused.hpp:2230
detail::ColumnMajorLapackMatrix< Scalar > real_triangular_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper, MatrixTranspose transpose=MatrixTranspose::None, bool unit_diagonal=false)
Solve a dense real triangular system through LAPACK trtrs.
Definition dense_subspace_unused.hpp:2867
RealSchurSelectedSubspace< Scalar > real_schur_selected_subspace(RealSchurDecomposition< Scalar > decomposition, std::vector< std::size_t > const &selected_blocks)
Compute the real Schur decomposition of a layout-right matrix through LAPACK gees.
Definition dense_subspace_unused.hpp:6685
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_positive_definite_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper)
Solve a dense real symmetric positive definite system through LAPACK potrf and potrs.
Definition dense_subspace_unused.hpp:3448
detail::ColumnMajorLapackMatrix< Scalar > apply_real_bidiagonal_right_factor(RealBidiagonalReduction< Scalar > const &reduction, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Right, MatrixTranspose transpose=MatrixTranspose::None)
Apply the right orthogonal factor P from a real bidiagonal reduction.
Definition dense_subspace_unused.hpp:5902
RealSymmetricPositiveDefiniteFactorization< Scalar > real_symmetric_positive_definite_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Compute a dense real SPD Cholesky factorization through LAPACK potrf.
Definition dense_subspace_unused.hpp:1779
RealSingularValueDecomposition< Scalar > real_singular_value_decomposition(detail::ColumnMajorLapackMatrix< Scalar > matrix, bool compute_vectors)
Compute a dense real singular value decomposition through LAPACK gesvd.
Definition dense_subspace_unused.hpp:6383
ComplexHermitianEigensystem< Real > complex_hermitian_eigensystem_divide_and_conquer(detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > matrix, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense complex Hermitian eigensystem through LAPACK heevd.
Definition dense_subspace_unused.hpp:4524
RealGeneralizedNonsymmetricBalance< Real > real_generalized_nonsymmetric_balance(detail::ColumnMajorLapackMatrix< Real > matrix, detail::ColumnMajorLapackMatrix< Real > metric, RealNonsymmetricBalanceJob job=RealNonsymmetricBalanceJob::Both)
Balance a dense real nonsymmetric matrix pencil through LAPACK ggbal.
Definition dense_subspace_unused.hpp:7043
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_positive_definite_inverse(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Invert a dense real SPD matrix through LAPACK potrf and potri.
Definition dense_subspace_unused.hpp:3697
TridiagonalEigensystem< Scalar > symmetric_tridiagonal_eigensystem_index_range(std::vector< Scalar > diagonal, std::vector< Scalar > subdiagonal, std::size_t first_index, std::size_t last_index, bool compute_vectors)
Solve a selected real symmetric tridiagonal eigensystem through LAPACK stevr.
Definition dense_subspace_unused.hpp:6622
RealRefinedLinearSolve< Scalar > real_refined_linear_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixTranspose transpose=MatrixTranspose::None)
Solve and refine a dense real linear system through LAPACK gerfs.
Definition dense_subspace_unused.hpp:2764
ComplexHermitianEigensystem< Real > complex_generalized_hermitian_eigensystem_index_range(detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > matrix, detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > metric, std::size_t first_index, std::size_t last_index, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a selected dense type-1 generalized complex Hermitian eigensystem through LAPACK hegvx.
Definition dense_subspace_unused.hpp:4769
MatrixTranspose
Matrix transpose mode for local dense Krylov operations.
Definition dense_linalg.hpp:78
RealSymmetricIndefiniteFactorization< Scalar > real_symmetric_indefinite_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Compute a dense real symmetric-indefinite Bunch-Kaufman factorization through LAPACK sytrf.
Definition dense_subspace_unused.hpp:3729
Scalar real_general_band_matrix_norm(RealGeneralBandMatrix< Scalar > band_matrix, MatrixNorm norm)
Compute a real general-band matrix norm through LAPACK langb.
Definition dense_subspace_unused.hpp:854
RealGeneralBandFactorization< Scalar > real_general_band_factorization(RealGeneralBandMatrix< Scalar > matrix)
Compute a real general-band LU factorization through LAPACK gbtrf.
Definition dense_subspace_unused.hpp:916
detail::ColumnMajorLapackMatrix< Scalar > apply_real_lq_factor(RealCompactLqFactorization< Scalar > const &factorization, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Right, MatrixTranspose transpose=MatrixTranspose::None)
Apply the orthogonal factor from a compact real LQ factorization.
Definition dense_subspace_unused.hpp:5040
RealCompactQlFactorization< Scalar > real_compact_ql_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a compact dense real QL factorization through LAPACK geqlf.
Definition dense_subspace_unused.hpp:5154
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_positive_definite_band_solve(RealSymmetricPositiveDefiniteBandMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a real SPD band system through LAPACK pbsv.
Definition dense_subspace_unused.hpp:1863
RealEquilibration< Scalar > real_general_band_power_of_two_equilibration(RealGeneralBandMatrix< Scalar > band_matrix)
Compute power-of-two real general-band equilibration factors through LAPACK gbequb.
Definition dense_subspace_unused.hpp:1691
RealSymmetricPositiveDefiniteTridiagonalFactorization< Scalar > real_symmetric_positive_definite_tridiagonal_factorization(RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > matrix)
Compute a real SPD tridiagonal factorization through LAPACK pttrf.
Definition dense_subspace_unused.hpp:2263
RealSymmetricEigensystem< Scalar > real_symmetric_eigensystem_index_range(detail::ColumnMajorLapackMatrix< Scalar > matrix, std::size_t first_index, std::size_t last_index, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a selected dense real symmetric eigensystem through LAPACK syevr.
Definition dense_subspace_unused.hpp:4214
Scalar real_symmetric_positive_definite_tridiagonal_one_norm(RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > const &matrix)
Compute the one-norm of a real SPD tridiagonal matrix.
Definition dense_subspace_unused.hpp:2327
RealSymmetricPositiveDefiniteEquilibration< Scalar > real_symmetric_positive_definite_equilibration(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute dense real SPD equilibration factors through LAPACK poequ.
Definition dense_subspace_unused.hpp:1751
Scalar real_symmetric_positive_definite_band_one_norm_reciprocal_condition_number(RealSymmetricPositiveDefiniteBandFactorization< Scalar > const &factorization, Scalar original_one_norm)
Estimate a real SPD band one-norm reciprocal condition number through LAPACK pbcon.
Definition dense_subspace_unused.hpp:2022
Scalar real_general_band_one_norm_reciprocal_condition_number(RealGeneralBandFactorization< Scalar > const &factorization, Scalar original_one_norm)
Estimate a real general-band one-norm reciprocal condition number through LAPACK gbcon.
Definition dense_subspace_unused.hpp:1443
RealSchurRightEigenvectors< Scalar > real_schur_right_eigenvectors(RealSchurDecomposition< Scalar > decomposition)
Compute right eigenvectors of a real Schur form through LAPACK trevc.
Definition dense_subspace_unused.hpp:6802
std::vector< Scalar > real_bidiagonal_singular_values(std::vector< Scalar > diagonal, std::vector< Scalar > offdiagonal, bool upper=true)
Compute singular values of a real bidiagonal matrix through LAPACK bdsqr.
Definition dense_subspace_unused.hpp:5539
RealSingularValueDecomposition< Scalar > real_singular_value_decomposition_divide_and_conquer(detail::ColumnMajorLapackMatrix< Scalar > matrix, bool compute_vectors)
Compute a dense real singular value decomposition through LAPACK gesdd.
Definition dense_subspace_unused.hpp:6439
RealSymmetricIndefiniteExpertLinearSolve< Scalar > real_symmetric_indefinite_expert_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper)
Solve a dense real symmetric-indefinite system with LAPACK sysvx diagnostics.
Definition dense_subspace_unused.hpp:3964
RealGeneralizedHessenbergReduction< Real > real_generalized_hessenberg_reduction(detail::ColumnMajorLapackMatrix< Real > matrix, detail::ColumnMajorLapackMatrix< Real > upper_triangular_metric, bool compute_vectors)
Reduce a real matrix pencil to generalized upper Hessenberg form through LAPACK gghrd.
Definition dense_subspace_unused.hpp:7148
RealRefinedLinearSolve< Scalar > real_general_tridiagonal_refined_solve(RealGeneralTridiagonalMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixTranspose transpose=MatrixTranspose::None)
Solve and refine a real general-tridiagonal linear system through LAPACK gtrfs.
Definition dense_subspace_unused.hpp:1291
RealSvdLeastSquares< Scalar > real_svd_least_squares(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, Scalar rcond=Scalar{100} *uni20::numeric_limits< Scalar >::epsilon())
Solve a dense real SVD-based least-squares problem through LAPACK gelss.
Definition dense_subspace_unused.hpp:3197
detail::ColumnMajorLapackMatrix< Scalar > real_bidiagonal_left_orthogonal_factor(RealBidiagonalReduction< Scalar > const &reduction)
Materialize the left orthogonal factor Q from a real bidiagonal reduction.
Definition dense_subspace_unused.hpp:5741
RealGeneralTridiagonalExpertLinearSolve< Scalar > real_general_tridiagonal_expert_linear_solve(RealGeneralTridiagonalMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixTranspose transpose=MatrixTranspose::None)
Solve a real general-tridiagonal linear system with LAPACK gtsvx diagnostics.
Definition dense_subspace_unused.hpp:1368
RealRefinedLinearSolve< Scalar > real_triangular_refined_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper, MatrixTranspose transpose=MatrixTranspose::None, bool unit_diagonal=false)
Solve and refine a dense real triangular system through LAPACK trrfs.
Definition dense_subspace_unused.hpp:2907
RealRankRevealingLeastSquares< Scalar > real_rank_revealing_least_squares(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, Scalar rcond=Scalar{100} *uni20::numeric_limits< Scalar >::epsilon())
Solve a dense real rank-revealing least-squares problem through LAPACK gelsy.
Definition dense_subspace_unused.hpp:3358
ComplexHermitianEigensystem< Real > complex_hermitian_eigensystem_index_range(detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > matrix, std::size_t first_index, std::size_t last_index, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a selected dense complex Hermitian eigensystem through LAPACK heevr.
Definition dense_subspace_unused.hpp:4577
RealSingularValueDecomposition< Scalar > real_singular_value_decomposition_index_range(detail::ColumnMajorLapackMatrix< Scalar > matrix, std::size_t first_index, std::size_t last_index, bool compute_vectors)
Compute a selected-index dense real SVD through LAPACK gesvdx.
Definition dense_subspace_unused.hpp:6498
detail::ColumnMajorLapackMatrix< Scalar > apply_real_qr_factor(RealCompactQrFactorization< Scalar > const &factorization, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Left, MatrixTranspose transpose=MatrixTranspose::None)
Apply the orthogonal factor from a compact real QR factorization.
Definition dense_subspace_unused.hpp:4885
RealSylvesterSolution< Scalar > real_sylvester_solve(detail::ColumnMajorLapackMatrix< Scalar > left, detail::ColumnMajorLapackMatrix< Scalar > right, detail::ColumnMajorLapackMatrix< Scalar > rhs, int sign=1, MatrixTranspose transpose_left=MatrixTranspose::None, MatrixTranspose transpose_right=MatrixTranspose::None)
Solve a dense real Sylvester equation through LAPACK trsyl.
Definition dense_subspace_unused.hpp:3045
RealRefinedLinearSolve< Scalar > real_symmetric_positive_definite_refined_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper)
Solve and refine a dense real SPD system through LAPACK porfs.
Definition dense_subspace_unused.hpp:3519
RealBidiagonalReduction< Scalar > real_bidiagonal_reduction(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Reduce a dense real matrix to bidiagonal form through LAPACK gebrd.
Definition dense_subspace_unused.hpp:5475
RealEquilibration< Scalar > real_equilibration(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute dense real row/column equilibration factors through LAPACK geequ.
Definition dense_subspace_unused.hpp:1725
RealSymmetricTridiagonalReduction< Scalar > real_symmetric_tridiagonal_reduction(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Reduce a dense real symmetric matrix to tridiagonal form through LAPACK sytrd.
Definition dense_subspace_unused.hpp:6134
RealBidiagonalSvd< Scalar > real_bidiagonal_svd_index_range(std::vector< Scalar > diagonal, std::vector< Scalar > offdiagonal, std::size_t first_index, std::size_t last_index, bool compute_vectors, bool upper=true)
Compute a selected-index SVD of a real bidiagonal matrix through LAPACK bdsvdx.
Definition dense_subspace_unused.hpp:5655
Scalar real_triangular_one_norm_reciprocal_condition_number(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper, bool unit_diagonal=false)
Estimate a dense real triangular one-norm reciprocal condition number through LAPACK trcon.
Definition dense_subspace_unused.hpp:3006
Scalar real_general_tridiagonal_one_norm_reciprocal_condition_number(RealGeneralTridiagonalFactorization< Scalar > const &factorization, Scalar original_one_norm)
Estimate a real general-tridiagonal one-norm reciprocal condition number through LAPACK gtcon.
Definition dense_subspace_unused.hpp:1217
RealEquilibration< Scalar > real_general_band_equilibration(RealGeneralBandMatrix< Scalar > band_matrix)
Compute real general-band row/column equilibration factors through LAPACK gbequ.
Definition dense_subspace_unused.hpp:1657
RealNonsymmetricBalanceJob
LAPACK balancing operations for a dense real nonsymmetric matrix.
Definition dense_subspace_unused.hpp:461
Scalar real_triangular_matrix_norm(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixNorm norm, MatrixFill triangle=MatrixFill::Upper, bool unit_diagonal=false)
Compute a dense real triangular or trapezoidal matrix norm through LAPACK lantr.
Definition dense_subspace_unused.hpp:790
uni20::linalg::MatrixRegion MatrixFill
Matrix region selected by LAPACK-style copy and set operations.
Definition dense_linalg.hpp:92
Scalar real_symmetric_positive_definite_tridiagonal_one_norm_reciprocal_condition_number(RealSymmetricPositiveDefiniteTridiagonalFactorization< Scalar > const &factorization, Scalar original_one_norm)
Estimate a real SPD tridiagonal one-norm reciprocal condition number through LAPACK ptcon.
Definition dense_subspace_unused.hpp:2363
MatrixSide
Matrix side selected by LAPACK-style multiply and solve operations.
Definition dense_linalg.hpp:86
RealNonsymmetricBalance< Real > real_nonsymmetric_balance(detail::ColumnMajorLapackMatrix< Real > matrix, RealNonsymmetricBalanceJob job=RealNonsymmetricBalanceJob::Both)
Reorder a layout-right complex Schur decomposition by moving selected entries to the front.
Definition dense_subspace_unused.hpp:6958
detail::ColumnMajorLapackMatrix< Scalar > real_general_tridiagonal_solve(RealGeneralTridiagonalMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a real general tridiagonal linear system through LAPACK gtsv.
Definition dense_subspace_unused.hpp:1044
RealSymmetricPositiveDefiniteTridiagonalExpertLinearSolve< Scalar > real_symmetric_positive_definite_tridiagonal_expert_linear_solve(RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a real SPD tridiagonal linear system with LAPACK ptsvx diagnostics.
Definition dense_subspace_unused.hpp:2466
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_tridiagonal_orthogonal_factor(RealSymmetricTridiagonalReduction< Scalar > const &reduction)
Generate the orthogonal factor from a compact real symmetric tridiagonal reduction.
Definition dense_subspace_unused.hpp:6191
RealExpertLinearSolve< Scalar > real_expert_linear_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve a dense real linear system with LAPACK gesvx diagnostics.
Definition dense_subspace_unused.hpp:2613
RealCompactRqFactorization< Scalar > real_compact_rq_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a compact dense real RQ factorization through LAPACK gerqf.
Definition dense_subspace_unused.hpp:5313
detail::ColumnMajorLapackMatrix< Scalar > real_symmetric_indefinite_inverse(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Invert a dense real symmetric-indefinite matrix through LAPACK sytrf and sytri.
Definition dense_subspace_unused.hpp:3920
MatrixNorm
LAPACK-compatible dense matrix norm selector.
Definition dense_linalg.hpp:96
RealSchurConditionEstimates< Scalar > real_schur_condition_estimates(RealSchurDecomposition< Scalar > decomposition)
Estimate Schur-form eigenvalue and eigenvector conditioning through LAPACK trsna.
Definition dense_subspace_unused.hpp:6892
RealQlFactorization< Scalar > real_ql_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a reduced dense real QL factorization through LAPACK geqlf and orgql.
Definition dense_subspace_unused.hpp:5254
RealLqFactorization< Scalar > real_lq_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a reduced dense real LQ factorization through LAPACK gelqf and orglq.
Definition dense_subspace_unused.hpp:5099
RealPivotedCholeskyFactorization< Scalar > real_pivoted_cholesky_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix, Scalar tolerance=Scalar{-1}, MatrixFill triangle=MatrixFill::Upper)
Compute a dense real pivoted Cholesky factorization through LAPACK pstrf.
Definition dense_subspace_unused.hpp:2523
detail::ColumnMajorLapackMatrix< Scalar > apply_real_rq_factor(RealCompactRqFactorization< Scalar > const &factorization, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Right, MatrixTranspose transpose=MatrixTranspose::None)
Apply the orthogonal factor from a compact real RQ factorization.
Definition dense_subspace_unused.hpp:5354
detail::ColumnMajorLapackMatrix< Real > real_generalized_nonsymmetric_balance_backtransform_right_vectors(detail::ColumnMajorLapackMatrix< Real > vectors, RealGeneralizedNonsymmetricBalance< Real > const &balance, RealNonsymmetricBalanceJob job=RealNonsymmetricBalanceJob::Both)
Backtransform real right eigenvectors after generalized pencil balancing.
Definition dense_subspace_unused.hpp:7099
RealGeneralTridiagonalMatrix< Scalar > real_general_tridiagonal_from_dense(detail::ColumnMajorLapackMatrix< Scalar > const &matrix)
Extract real general tridiagonal storage from a dense matrix.
Definition dense_subspace_unused.hpp:1010
RealPivotedQrFactorization< Scalar > real_pivoted_qr_factorization(detail::ColumnMajorLapackMatrix< Scalar > matrix)
Compute a reduced dense real pivoted QR factorization through LAPACK geqp3.
Definition dense_subspace_unused.hpp:6305
detail::ColumnMajorLapackMatrix< Scalar > apply_real_symmetric_tridiagonal_orthogonal_factor(RealSymmetricTridiagonalReduction< Scalar > const &reduction, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Left, MatrixTranspose transpose=MatrixTranspose::None)
Apply the orthogonal factor from a compact real symmetric tridiagonal reduction.
Definition dense_subspace_unused.hpp:6242
Scalar real_symmetric_positive_definite_one_norm_reciprocal_condition_number(detail::ColumnMajorLapackMatrix< Scalar > matrix, MatrixFill triangle=MatrixFill::Upper)
Estimate a dense real SPD one-norm reciprocal condition number through LAPACK pocon.
Definition dense_subspace_unused.hpp:3627
RealSymmetricEigensystem< Scalar > real_symmetric_eigensystem_divide_and_conquer(detail::ColumnMajorLapackMatrix< Scalar > matrix, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense real symmetric eigensystem through LAPACK syevd.
Definition dense_subspace_unused.hpp:4163
RealRefinedLinearSolve< Scalar > real_symmetric_positive_definite_band_refined_solve(RealSymmetricPositiveDefiniteBandMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides)
Solve and refine a real SPD band linear system through LAPACK pbrfs.
Definition dense_subspace_unused.hpp:2082
RealGeneralizedSchurDecomposition< Real > reorder_real_generalized_schur(RealGeneralizedSchurDecomposition< Real > decomposition, std::vector< std::size_t > const &leading_block_order)
Reorder a generalized real Schur decomposition by moving selected blocks to the front.
Definition dense_subspace_unused.hpp:7408
ComplexHermitianEigensystem< Real > complex_generalized_hermitian_eigensystem(detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > matrix, detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > metric, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense type-1 generalized complex Hermitian eigensystem through LAPACK hegv.
Definition dense_subspace_unused.hpp:4647
detail::ColumnMajorLapackMatrix< Scalar > apply_real_hessenberg_orthogonal_factor(RealHessenbergReduction< Scalar > const &reduction, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Left, MatrixTranspose transpose=MatrixTranspose::None)
Apply the orthogonal factor from a compact real Hessenberg reduction.
Definition dense_subspace_unused.hpp:6067
detail::ColumnMajorLapackMatrix< Scalar > real_hessenberg_orthogonal_factor(RealHessenbergReduction< Scalar > const &reduction)
Generate the orthogonal factor from a compact real Hessenberg reduction.
Definition dense_subspace_unused.hpp:6014
detail::ColumnMajorLapackMatrix< Scalar > apply_real_ql_factor(RealCompactQlFactorization< Scalar > const &factorization, detail::ColumnMajorLapackMatrix< Scalar > target, MatrixSide side=MatrixSide::Left, MatrixTranspose transpose=MatrixTranspose::None)
Apply the orthogonal factor from a compact real QL factorization.
Definition dense_subspace_unused.hpp:5195
Scalar real_lu_one_norm_reciprocal_condition_number(RealLuFactorization< Scalar > const &factorization, Scalar original_one_norm)
Estimate the one-norm reciprocal condition number from an LU factorization.
Definition dense_subspace_unused.hpp:2814
RealRefinedLinearSolve< Scalar > real_symmetric_indefinite_refined_solve(detail::ColumnMajorLapackMatrix< Scalar > coefficients, detail::ColumnMajorLapackMatrix< Scalar > right_hand_sides, MatrixFill triangle=MatrixFill::Upper)
Solve and refine a dense real symmetric-indefinite system through LAPACK syrfs.
Definition dense_subspace_unused.hpp:3862
RealSymmetricEigensystem< Scalar > real_generalized_symmetric_eigensystem_divide_and_conquer(detail::ColumnMajorLapackMatrix< Scalar > matrix, detail::ColumnMajorLapackMatrix< Scalar > metric, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense type-1 generalized real symmetric eigensystem through LAPACK sygvd.
Definition dense_subspace_unused.hpp:4341
RealGeneralBandMatrix< Scalar > real_general_band_from_dense(detail::ColumnMajorLapackMatrix< Scalar > const &matrix, std::size_t lower_bandwidth, std::size_t upper_bandwidth)
Pack a dense real square matrix into LAPACK general-band factor storage.
Definition dense_subspace_unused.hpp:817
Scalar real_symmetric_positive_definite_band_one_norm(RealSymmetricPositiveDefiniteBandMatrix< Scalar > const &matrix)
Compute the one-norm of a real SPD band matrix.
Definition dense_subspace_unused.hpp:1962
ComplexHermitianEigensystem< Real > complex_generalized_hermitian_eigensystem_divide_and_conquer(detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > matrix, detail::ColumnMajorLapackMatrix< uni20::detail::standard_complex< Real > > metric, bool compute_vectors, MatrixFill triangle=MatrixFill::Upper)
Solve a dense type-1 generalized complex Hermitian eigensystem through LAPACK hegvd.
Definition dense_subspace_unused.hpp:4702
void getrf(blas_int m, blas_int n, Scalar *a, blas_int lda, blas_int *ipiv)
Compute a real dense general LU factorization through the configured LAPACK backend.
Definition lapack.hpp:402
void geqp3(blas_int m, blas_int n, Scalar *a, blas_int lda, blas_int *jpvt, Scalar *tau, Scalar *work, blas_int lwork)
Compute a real dense pivoted QR factorization.
Definition lapack.hpp:647
void sygv(blas_int itype, char jobz, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *w, Scalar *work, blas_int lwork)
Compute eigenvalues and optionally eigenvectors of a real generalized symmetric-definite problem.
Definition lapack.hpp:692
Scalar lange(char norm, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *work)
Compute a dense real matrix norm through the configured LAPACK backend.
Definition lapack.hpp:185
void gbsv(blas_int n, blas_int kl, blas_int ku, blas_int nrhs, Scalar *ab, blas_int ldab, blas_int *ipiv, Scalar *b, blas_int ldb)
Solve a real general-band linear system through the configured LAPACK backend.
Definition lapack.hpp:235
void syevd(char jobz, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *w, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Compute eigenvalues and optionally eigenvectors of a real symmetric matrix by divide and conquer.
Definition lapack.hpp:672
void ptsv(blas_int n, blas_int nrhs, Scalar *d, Scalar *e, Scalar *b, blas_int ldb)
Solve a real symmetric positive-definite tridiagonal linear system.
Definition lapack.hpp:1537
void ormql(char side, char trans, blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by the implicit real Q factor from a QL factorization.
Definition lapack.hpp:611
void bdsqr(char uplo, blas_int n, blas_int ncvt, blas_int nru, blas_int ncc, Scalar *d, Scalar *e, Scalar *vt, blas_int ldvt, Scalar *u, blas_int ldu, Scalar *c, blas_int ldc, Scalar *work)
Compute singular values of a real bidiagonal matrix.
Definition lapack.hpp:1247
void ggbak(char job, char side, blas_int n, blas_int first, blas_int last, Scalar *lscale, Scalar *rscale, blas_int vector_count, Scalar *vectors, blas_int leading_dimension)
Back-transform generalized nonsymmetric eigenvectors after pencil balancing.
Definition lapack.hpp:1004
void gbequ(bool power_of_two, blas_int m, blas_int n, blas_int kl, blas_int ku, Scalar *ab, blas_int ldab, Scalar *row_scale, Scalar *column_scale, Scalar &row_condition, Scalar &column_condition, Scalar &max_abs)
Compute real general-band row/column equilibration factors.
Definition lapack.hpp:296
void potrs(char uplo, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb)
Solve using an existing real dense Cholesky factorization.
Definition lapack.hpp:1316
void bdsdc(char uplo, char compq, blas_int n, Scalar *d, Scalar *e, Scalar *u, blas_int ldu, Scalar *vt, blas_int ldvt, Scalar *q, blas_int *iq, Scalar *work, blas_int *iwork)
Compute the singular value decomposition of a real bidiagonal matrix.
Definition lapack.hpp:1256
Scalar langb(char norm, blas_int n, blas_int kl, blas_int ku, Scalar *ab, blas_int ldab, Scalar *work)
Compute a real general-band matrix norm through the configured LAPACK backend.
Definition lapack.hpp:228
bool trsyl(char trans_a, char trans_b, blas_int sign, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *c, blas_int ldc, Scalar &scale)
Solve a dense real Sylvester equation.
Definition lapack.hpp:1471
void sytrf(char uplo, blas_int n, Scalar *a, blas_int lda, blas_int *ipiv, Scalar *work, blas_int lwork)
Compute a dense real symmetric-indefinite Bunch-Kaufman factorization.
Definition lapack.hpp:1377
void gelsy(blas_int m, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, blas_int *jpvt, Scalar rcond, blas_int &rank, Scalar *work, blas_int lwork)
Solve a real dense general least-squares problem by complete orthogonal factorization.
Definition lapack.hpp:516
void gghrd(char compq, char compz, blas_int n, blas_int first, blas_int last, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *q, blas_int ldq, Scalar *z, blas_int ldz)
Reduce a real matrix pencil to generalized Hessenberg form.
Definition lapack.hpp:1037
void poequ(blas_int n, Scalar *a, blas_int lda, Scalar *scale, Scalar &scale_condition, Scalar &max_abs)
Compute real dense SPD equilibration factors.
Definition lapack.hpp:1355
void sygvx(blas_int itype, char jobz, char range, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar vl, Scalar vu, blas_int il, blas_int iu, Scalar abstol, blas_int &selected_count, Scalar *w, Scalar *z, blas_int ldz, Scalar *work, blas_int lwork, blas_int *iwork, blas_int *ifail)
Compute selected eigenvalues and optionally eigenvectors of a real generalized symmetric-definite pro...
Definition lapack.hpp:712
void gttrf(blas_int n, Scalar *dl, Scalar *d, Scalar *du, Scalar *du2, blas_int *ipiv)
Compute a real tridiagonal LU factorization through the configured LAPACK backend.
Definition lapack.hpp:1488
void pbsv(char uplo, blas_int n, blas_int kd, blas_int nrhs, Scalar *ab, blas_int ldab, Scalar *b, blas_int ldb)
Solve a real symmetric positive-definite band linear system.
Definition lapack.hpp:306
void bdsvdx(char uplo, char jobz, char range, blas_int n, Scalar *d, Scalar *e, Scalar vl, Scalar vu, blas_int il, blas_int iu, blas_int &selected_count, Scalar *singular_values, Scalar *z, blas_int ldz, Scalar *work, blas_int *iwork)
Compute selected singular values/vectors of a real bidiagonal matrix.
Definition lapack.hpp:1269
void orgqr(blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Generate an explicit orthogonal or unitary Q factor from a QR factorization.
Definition lapack.hpp:561
void ormrq(char side, char trans, blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by the implicit real Q factor from an RQ factorization.
Definition lapack.hpp:620
bool gesvx(char fact, char trans, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *af, blas_int ldaf, blas_int *ipiv, char &equed, Scalar *row_scale, Scalar *column_scale, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Solve a real dense general linear system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:382
bool pbsvx(char fact, char uplo, blas_int n, blas_int kd, blas_int nrhs, Scalar *ab, blas_int ldab, Scalar *afb, blas_int ldafb, char &equed, Scalar *scale, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Solve a real symmetric positive-definite band system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:354
void heev(char jobz, char uplo, blas_int n, uni20::detail::standard_complex< Real > *a, blas_int lda, Real *w, uni20::detail::standard_complex< Real > *work, blas_int lwork, Real *rwork)
Compute eigenvalues and optionally eigenvectors of a complex Hermitian matrix.
Definition lapack.hpp:723
void gesvdx(char jobu, char jobvt, char range, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar vl, Scalar vu, blas_int il, blas_int iu, blas_int &selected_count, Scalar *singular_values, Scalar *u, blas_int ldu, Scalar *vt, blas_int ldvt, Scalar *work, blas_int lwork, blas_int *iwork)
Compute selected singular values/vectors of a real dense matrix.
Definition lapack.hpp:1224
void sytri(char uplo, blas_int n, Scalar *a, blas_int lda, blas_int const *ipiv, Scalar *work)
Invert a dense real symmetric-indefinite matrix from its factorization.
Definition lapack.hpp:1393
Scalar lantr(char norm, char uplo, char diag, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *work)
Compute a dense real triangular or trapezoidal matrix norm through the configured LAPACK backend.
Definition lapack.hpp:213
void geqrf(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Compute a real or complex dense QR factorization through the configured LAPACK backend.
Definition lapack.hpp:529
void ormhr(char side, char trans, blas_int m, blas_int n, blas_int first, blas_int last, Scalar *a, blas_int lda, Scalar const *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by an implicit real orthogonal factor from Hessenberg reduction.
Definition lapack.hpp:1159
void porfs(char uplo, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *factors, blas_int factor_lda, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a real dense SPD linear-system solve and return LAPACK diagnostics.
Definition lapack.hpp:1324
void ggevx(char balanc, char jobvl, char jobvr, char sense, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *alphar, Scalar *alphai, Scalar *beta, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, blas_int &ilo, blas_int &ihi, Scalar *lscale, Scalar *rscale, Scalar &abnrm, Scalar &bbnrm, Scalar *rconde, Scalar *rcondv, Scalar *work, blas_int lwork, blas_int *iwork, blas_int *bwork)
Compute generalized real nonsymmetric eigenpairs with balancing and condition estimates.
Definition lapack.hpp:978
void tgexc(bool wantq, bool wantz, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *q, blas_int ldq, Scalar *z, blas_int ldz, blas_int &first, blas_int &last, Scalar *work, blas_int lwork)
Reorder adjacent blocks in a generalized real Schur form.
Definition lapack.hpp:1065
void potri(char uplo, blas_int n, Scalar *a, blas_int lda)
Invert a real dense matrix from an existing Cholesky factorization.
Definition lapack.hpp:1304
void tgsna(char job, char howmny, blas_int *select, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, Scalar *reciprocal_eigenvalue_condition_numbers, Scalar *reciprocal_eigenvector_condition_numbers, blas_int mm, blas_int &computed_estimates, Scalar *work, blas_int lwork, blas_int *iwork)
Estimate reciprocal condition numbers for generalized real Schur eigenpairs.
Definition lapack.hpp:1116
void orgtr(char uplo, blas_int n, Scalar *a, blas_int lda, Scalar const *tau, Scalar *work, blas_int lwork)
Generate an explicit real orthogonal factor from symmetric tridiagonal reduction.
Definition lapack.hpp:1151
void trtrs(char uplo, char trans, char diag, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb)
Solve a dense real triangular system.
Definition lapack.hpp:1434
void syevr(char jobz, char range, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar vl, Scalar vu, blas_int il, blas_int iu, Scalar abstol, blas_int &selected_count, Scalar *w, Scalar *z, blas_int ldz, blas_int *isuppz, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Compute selected eigenvalues and optionally eigenvectors of a real symmetric matrix.
Definition lapack.hpp:681
void gerqf(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Compute a real dense RQ factorization through the configured LAPACK backend.
Definition lapack.hpp:553
void syev(char jobz, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *w, Scalar *work, blas_int lwork)
Compute eigenvalues and optionally eigenvectors of a real symmetric matrix.
Definition lapack.hpp:664
void geqlf(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Compute a real dense QL factorization through the configured LAPACK backend.
Definition lapack.hpp:545
void gerfs(char trans, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *factors, blas_int factor_lda, blas_int const *ipiv, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a real dense general linear-system solve and return LAPACK diagnostics.
Definition lapack.hpp:436
void gelsd(blas_int m, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *s, Scalar rcond, blas_int &rank, Scalar *work, blas_int lwork, blas_int *iwork)
Solve a real dense general least-squares problem by divide-and-conquer SVD.
Definition lapack.hpp:507
void gttrs(char trans, blas_int n, blas_int nrhs, Scalar *dl, Scalar *d, Scalar *du, Scalar *du2, blas_int const *ipiv, Scalar *b, blas_int ldb)
Solve using an existing real tridiagonal LU factorization.
Definition lapack.hpp:1496
Scalar gtcon(char norm, blas_int n, Scalar *dl, Scalar *d, Scalar *du, Scalar *du2, blas_int const *ipiv, Scalar matrix_norm, Scalar *work, blas_int *iwork)
Estimate a real tridiagonal reciprocal condition number.
Definition lapack.hpp:1505
void hgeqz(char job, char compq, char compz, blas_int n, blas_int first, blas_int last, Scalar *h, blas_int ldh, Scalar *t, blas_int ldt, Scalar *alphar, Scalar *alphai, Scalar *beta, Scalar *q, blas_int ldq, Scalar *z, blas_int ldz, Scalar *work, blas_int lwork)
Compute a generalized Schur form from a real Hessenberg-triangular pencil.
Definition lapack.hpp:1050
void gebal(char job, blas_int n, Scalar *a, blas_int lda, blas_int &first, blas_int &last, Scalar *scale)
Balance a real nonsymmetric matrix before eigenanalysis.
Definition lapack.hpp:810
void stevr(char jobz, char range, blas_int n, Scalar *d, Scalar *e, Scalar vl, Scalar vu, blas_int il, blas_int iu, Scalar abstol, blas_int &selected_count, Scalar *w, Scalar *z, blas_int ldz, blas_int *isuppz, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Compute selected eigenvalues/eigenvectors of a real symmetric tridiagonal matrix.
Definition lapack.hpp:1615
void gebak(char job, char side, blas_int n, blas_int first, blas_int last, Scalar *scale, blas_int vector_count, Scalar *vectors, blas_int leading_dimension)
Back-transform real nonsymmetric eigenvectors after balancing.
Definition lapack.hpp:822
void orgrq(blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Generate an explicit real Q factor from an RQ factorization.
Definition lapack.hpp:585
Scalar gbcon(char norm, blas_int n, blas_int kl, blas_int ku, Scalar *ab, blas_int ldab, blas_int const *ipiv, Scalar anorm, Scalar *work, blas_int *iwork)
Estimate a real general-band reciprocal condition number.
Definition lapack.hpp:261
void gels(char trans, blas_int m, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *work, blas_int lwork)
Solve a real dense general least-squares problem through the configured LAPACK backend.
Definition lapack.hpp:485
void orglq(blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Generate an explicit orthogonal or unitary Q factor from an LQ factorization.
Definition lapack.hpp:569
void gbtrf(blas_int m, blas_int n, blas_int kl, blas_int ku, Scalar *ab, blas_int ldab, blas_int *ipiv)
Compute a real general-band LU factorization through the configured LAPACK backend.
Definition lapack.hpp:244
void gelss(blas_int m, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *s, Scalar rcond, blas_int &rank, Scalar *work, blas_int lwork)
Solve a real dense general least-squares problem by SVD.
Definition lapack.hpp:498
void gbrfs(char trans, blas_int n, blas_int kl, blas_int ku, blas_int nrhs, Scalar *ab, blas_int ldab, Scalar *afb, blas_int ldafb, blas_int const *ipiv, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a real general-band linear-system solve and return LAPACK diagnostics.
Definition lapack.hpp:272
bool pstrf(char uplo, blas_int n, Scalar *a, blas_int lda, blas_int *pivots, blas_int &rank, Scalar tolerance, Scalar *work)
Compute a real dense pivoted Cholesky factorization.
Definition lapack.hpp:1291
void trsna(char job, char howmny, blas_int *select, blas_int n, Scalar *t, blas_int ldt, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, Scalar *reciprocal_eigenvalue_condition_numbers, Scalar *reciprocal_eigenvector_condition_numbers, blas_int mm, blas_int &computed_estimates, Scalar *work, blas_int ldwork, blas_int *iwork)
Estimate reciprocal condition numbers for real Schur eigenpairs.
Definition lapack.hpp:950
Scalar lansy(char norm, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *work)
Compute a dense real symmetric matrix norm through the configured LAPACK backend.
Definition lapack.hpp:199
void gehrd(blas_int n, blas_int first, blas_int last, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Reduce a real dense general matrix to upper Hessenberg form.
Definition lapack.hpp:638
void trrfs(char uplo, char trans, char diag, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a dense real triangular solve and return LAPACK diagnostics.
Definition lapack.hpp:1443
bool gbsvx(char fact, char trans, blas_int n, blas_int kl, blas_int ku, blas_int nrhs, Scalar *ab, blas_int ldab, Scalar *afb, blas_int ldafb, blas_int *ipiv, char &equed, Scalar *row_scale, Scalar *column_scale, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Solve a real general-band linear system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:283
void gtrfs(char trans, blas_int n, blas_int nrhs, Scalar *dl, Scalar *d, Scalar *du, Scalar *dlf, Scalar *df, Scalar *duf, Scalar *du2, blas_int const *ipiv, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a real tridiagonal linear-system solve and return LAPACK diagnostics.
Definition lapack.hpp:1516
void sygvd(blas_int itype, char jobz, char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *w, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Compute eigenvalues and optionally eigenvectors of a real generalized symmetric-definite problem by d...
Definition lapack.hpp:703
void geevx(char balanc, char jobvl, char jobvr, char sense, blas_int n, Scalar *a, blas_int lda, Scalar *wr, Scalar *wi, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, blas_int &ilo, blas_int &ihi, Scalar *scale, Scalar &abnrm, Scalar *rconde, Scalar *rcondv, Scalar *work, blas_int lwork, blas_int *iwork)
Compute real nonsymmetric eigenpairs with balancing and condition estimates.
Definition lapack.hpp:799
Scalar pbcon(char uplo, blas_int n, blas_int kd, Scalar *ab, blas_int ldab, Scalar anorm, Scalar *work, blas_int *iwork)
Estimate a real symmetric positive-definite band reciprocal condition number.
Definition lapack.hpp:333
void trtri(char uplo, char diag, blas_int n, Scalar *a, blas_int lda)
Invert a dense real triangular matrix.
Definition lapack.hpp:1453
void gbtrs(char trans, blas_int n, blas_int kl, blas_int ku, blas_int nrhs, Scalar *ab, blas_int ldab, blas_int const *ipiv, Scalar *b, blas_int ldb)
Solve using an existing real general-band LU factorization.
Definition lapack.hpp:252
void gesv(blas_int n, blas_int nrhs, Scalar *a, blas_int lda, blas_int *ipiv, Scalar *b, blas_int ldb)
Solve a real dense general linear system through the configured LAPACK backend.
Definition lapack.hpp:365
void orgql(blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Generate an explicit real Q factor from a QL factorization.
Definition lapack.hpp:577
void trsen(char job, char compq, blas_int *select, blas_int n, Scalar *t, blas_int ldt, Scalar *q, blas_int ldq, Scalar *wr, Scalar *wi, blas_int &selected_dimension, Scalar &reciprocal_eigenvalue_cluster_condition, Scalar &reciprocal_invariant_subspace_condition, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Reorder selected blocks in a real Schur form and estimate invariant subspace conditioning.
Definition lapack.hpp:915
void gebrd(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *d, Scalar *e, Scalar *tauq, Scalar *taup, Scalar *work, blas_int lwork)
Reduce a real dense general matrix to bidiagonal form.
Definition lapack.hpp:629
void getri(blas_int n, Scalar *a, blas_int lda, blas_int *ipiv, Scalar *work, blas_int lwork)
Invert a real dense general matrix from an existing LU factorization.
Definition lapack.hpp:447
void ormlq(char side, char trans, blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by the implicit real Q factor from an LQ factorization.
Definition lapack.hpp:602
void orgbr(char vect, blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Generate an explicit real orthogonal factor from bidiagonal reduction.
Definition lapack.hpp:1133
void ptrfs(blas_int n, blas_int nrhs, Scalar *d, Scalar *e, Scalar *df, Scalar *ef, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work)
Refine a real symmetric positive-definite tridiagonal solve and return LAPACK diagnostics.
Definition lapack.hpp:1572
void trevc(char side, char howmny, blas_int *select, blas_int n, Scalar *t, blas_int ldt, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, blas_int mm, blas_int &computed_vectors, Scalar *work)
Compute eigenvectors of a real upper quasi-triangular Schur form.
Definition lapack.hpp:936
void gtsv(blas_int n, blas_int nrhs, Scalar *dl, Scalar *d, Scalar *du, Scalar *b, blas_int ldb)
Solve a real tridiagonal linear system through the configured LAPACK backend.
Definition lapack.hpp:1480
void orghr(blas_int n, blas_int first, blas_int last, Scalar *a, blas_int lda, Scalar const *tau, Scalar *work, blas_int lwork)
Generate an explicit real orthogonal factor from Hessenberg reduction.
Definition lapack.hpp:1142
void heevr(char jobz, char range, char uplo, blas_int n, uni20::detail::standard_complex< Real > *a, blas_int lda, Real vl, Real vu, blas_int il, blas_int iu, Real abstol, blas_int &selected_count, Real *w, uni20::detail::standard_complex< Real > *z, blas_int ldz, blas_int *isuppz, uni20::detail::standard_complex< Real > *work, blas_int lwork, Real *rwork, blas_int lrwork, blas_int *iwork, blas_int liwork)
Compute selected eigenvalues and optionally eigenvectors of a complex Hermitian matrix.
Definition lapack.hpp:742
bool posvx(char fact, char uplo, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *af, blas_int ldaf, char &equed, Scalar *scale, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Solve a real dense SPD linear system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:1335
void sytrs(char uplo, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, blas_int const *ipiv, Scalar *b, blas_int ldb)
Solve using an existing dense real symmetric-indefinite factorization.
Definition lapack.hpp:1385
void getrs(char trans, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, blas_int const *ipiv, Scalar *b, blas_int ldb)
Solve using an existing real dense general LU factorization.
Definition lapack.hpp:418
void hegvd(blas_int itype, char jobz, char uplo, blas_int n, uni20::detail::standard_complex< Real > *a, blas_int lda, uni20::detail::standard_complex< Real > *b, blas_int ldb, Real *w, uni20::detail::standard_complex< Real > *work, blas_int lwork, Real *rwork, blas_int lrwork, blas_int *iwork, blas_int liwork)
Compute eigenvalues and optionally eigenvectors of a complex generalized Hermitian-definite problem b...
Definition lapack.hpp:766
void geequ(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *row_scale, Scalar *column_scale, Scalar &row_condition, Scalar &column_condition, Scalar &max_abs)
Compute real dense general row/column equilibration factors.
Definition lapack.hpp:393
void sytrd(char uplo, blas_int n, Scalar *a, blas_int lda, Scalar *d, Scalar *e, Scalar *tau, Scalar *work, blas_int lwork)
Reduce a real dense symmetric matrix to tridiagonal form.
Definition lapack.hpp:655
void pbtrs(char uplo, blas_int n, blas_int kd, blas_int nrhs, Scalar *ab, blas_int ldab, Scalar *b, blas_int ldb)
Solve using an existing real symmetric positive-definite band Cholesky factorization.
Definition lapack.hpp:321
void ggbal(char job, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, blas_int &first, blas_int &last, Scalar *lscale, Scalar *rscale, Scalar *work)
Balance a real nonsymmetric matrix pencil before generalized eigenanalysis.
Definition lapack.hpp:991
void pttrf(blas_int n, Scalar *d, Scalar *e)
Compute a real symmetric positive-definite tridiagonal factorization.
Definition lapack.hpp:1544
Scalar trcon(char norm, char uplo, char diag, blas_int n, Scalar *a, blas_int lda, Scalar *work, blas_int *iwork)
Estimate a dense real triangular reciprocal condition number.
Definition lapack.hpp:1461
void pttrs(blas_int n, blas_int nrhs, Scalar *d, Scalar *e, Scalar *b, blas_int ldb)
Solve using an existing real symmetric positive-definite tridiagonal factorization.
Definition lapack.hpp:1551
void hegvx(blas_int itype, char jobz, char range, char uplo, blas_int n, uni20::detail::standard_complex< Real > *a, blas_int lda, uni20::detail::standard_complex< Real > *b, blas_int ldb, Real vl, Real vu, blas_int il, blas_int iu, Real abstol, blas_int &selected_count, Real *w, uni20::detail::standard_complex< Real > *z, blas_int ldz, uni20::detail::standard_complex< Real > *work, blas_int lwork, Real *rwork, blas_int *iwork, blas_int *ifail)
Compute selected eigenvalues and optionally eigenvectors of a complex generalized Hermitian-definite ...
Definition lapack.hpp:777
void hegv(blas_int itype, char jobz, char uplo, blas_int n, uni20::detail::standard_complex< Real > *a, blas_int lda, uni20::detail::standard_complex< Real > *b, blas_int ldb, Real *w, uni20::detail::standard_complex< Real > *work, blas_int lwork, Real *rwork)
Compute eigenvalues and optionally eigenvectors of a complex generalized Hermitian-definite problem.
Definition lapack.hpp:755
void potrf(char uplo, blas_int n, Scalar *a, blas_int lda)
Compute a real dense Cholesky factorization.
Definition lapack.hpp:1279
void heevd(char jobz, char uplo, blas_int n, uni20::detail::standard_complex< Real > *a, blas_int lda, Real *w, uni20::detail::standard_complex< Real > *work, blas_int lwork, Real *rwork, blas_int lrwork, blas_int *iwork, blas_int liwork)
Compute eigenvalues and optionally eigenvectors of a complex Hermitian matrix by divide and conquer.
Definition lapack.hpp:732
void syrfs(char uplo, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *factors, blas_int factor_lda, blas_int const *ipiv, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a dense real symmetric-indefinite solve and return LAPACK diagnostics.
Definition lapack.hpp:1401
void ormtr(char side, char uplo, char trans, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar const *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by an implicit real orthogonal factor from symmetric tridiagonal reduction.
Definition lapack.hpp:1168
Scalar ptcon(blas_int n, Scalar *d, Scalar *e, Scalar matrix_norm, Scalar *work)
Estimate a real symmetric positive-definite tridiagonal reciprocal condition number.
Definition lapack.hpp:1562
Scalar sycon(char uplo, blas_int n, Scalar *a, blas_int lda, blas_int const *ipiv, Scalar matrix_one_norm, Scalar *work, blas_int *iwork)
Estimate a dense real symmetric-indefinite reciprocal condition number.
Definition lapack.hpp:1423
void pbtrf(char uplo, blas_int n, blas_int kd, Scalar *ab, blas_int ldab)
Compute a real symmetric positive-definite band Cholesky factorization.
Definition lapack.hpp:313
void ormbr(char vect, char side, char trans, blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by an implicit real orthogonal factor from bidiagonal reduction.
Definition lapack.hpp:1177
void pbrfs(char uplo, blas_int n, blas_int kd, blas_int nrhs, Scalar *ab, blas_int ldab, Scalar *afb, blas_int ldafb, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Refine a real symmetric positive-definite band solve and return LAPACK diagnostics.
Definition lapack.hpp:343
Scalar gecon(char norm, blas_int n, Scalar const *a, blas_int lda, Scalar anorm, Scalar *work, blas_int *iwork)
Estimate a real dense general reciprocal condition number.
Definition lapack.hpp:464
void stevd(char jobz, blas_int n, Scalar *d, Scalar *e, Scalar *z, blas_int ldz, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Compute a real symmetric tridiagonal eigensystem by divide-and-conquer.
Definition lapack.hpp:1606
void ggev(char jobvl, char jobvr, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *alphar, Scalar *alphai, Scalar *beta, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, Scalar *work, blas_int lwork)
Compute generalized eigenvalues and optionally eigenvectors of a real nonsymmetric matrix pencil.
Definition lapack.hpp:967
void gelqf(blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *tau, Scalar *work, blas_int lwork)
Compute a real or complex dense LQ factorization through the configured LAPACK backend.
Definition lapack.hpp:537
Scalar pocon(char uplo, blas_int n, Scalar *a, blas_int lda, Scalar matrix_one_norm, Scalar *work, blas_int *iwork)
Estimate a real dense SPD reciprocal condition number.
Definition lapack.hpp:1367
void tgevc(char side, char howmny, blas_int *select, blas_int n, Scalar *s, blas_int lds, Scalar *p, blas_int ldp, Scalar *vl, blas_int ldvl, Scalar *vr, blas_int ldvr, blas_int mm, blas_int &computed_vectors, Scalar *work)
Compute eigenvectors of a generalized real Schur form.
Definition lapack.hpp:1102
void gges(char jobvsl, char jobvsr, char sort, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, blas_int &selected_dimension, Scalar *alphar, Scalar *alphai, Scalar *beta, Scalar *vsl, blas_int ldvsl, Scalar *vsr, blas_int ldvsr, Scalar *work, blas_int lwork, blas_int *bwork)
Compute a generalized real Schur form of a real nonsymmetric matrix pencil.
Definition lapack.hpp:1018
void tgsen(blas_int ijob, bool wantq, bool wantz, blas_int *select, blas_int n, Scalar *a, blas_int lda, Scalar *b, blas_int ldb, Scalar *alphar, Scalar *alphai, Scalar *beta, Scalar *q, blas_int ldq, Scalar *z, blas_int ldz, blas_int &selected_dimension, Scalar &pl, Scalar &pr, Scalar *dif, Scalar *work, blas_int lwork, blas_int *iwork, blas_int liwork)
Reorder selected blocks in a generalized real Schur form and estimate conditioning.
Definition lapack.hpp:1082
bool sysvx(char fact, char uplo, blas_int n, blas_int nrhs, Scalar *a, blas_int lda, Scalar *af, blas_int ldaf, blas_int *ipiv, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int lwork, blas_int *iwork)
Solve a dense real symmetric-indefinite system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:1412
void gesvd(char jobu, char jobvt, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *s, Scalar *u, blas_int ldu, Scalar *vt, blas_int ldvt, Scalar *work, blas_int lwork)
Compute a real dense singular value decomposition.
Definition lapack.hpp:1186
void gesdd(char jobz, blas_int m, blas_int n, Scalar *a, blas_int lda, Scalar *s, Scalar *u, blas_int ldu, Scalar *vt, blas_int ldvt, Scalar *work, blas_int lwork, blas_int *iwork)
Compute a real dense divide-and-conquer singular value decomposition.
Definition lapack.hpp:1205
bool ptsvx(char fact, blas_int n, blas_int nrhs, Scalar *d, Scalar *e, Scalar *df, Scalar *ef, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work)
Solve a real symmetric positive-definite tridiagonal system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:1581
bool gtsvx(char fact, char trans, blas_int n, blas_int nrhs, Scalar *dl, Scalar *d, Scalar *du, Scalar *dlf, Scalar *df, Scalar *duf, Scalar *du2, blas_int *ipiv, Scalar *b, blas_int ldb, Scalar *x, blas_int ldx, Scalar &rcond, Scalar *forward_error, Scalar *backward_error, Scalar *work, blas_int *iwork)
Solve a real tridiagonal linear system with LAPACK expert-driver diagnostics.
Definition lapack.hpp:1527
void ormqr(char side, char trans, blas_int m, blas_int n, blas_int k, Scalar *a, blas_int lda, Scalar *tau, Scalar *c, blas_int ldc, Scalar *work, blas_int lwork)
Multiply by the implicit real Q factor from a QR factorization.
Definition lapack.hpp:593
auto matrix_norm_host(BackendSelector selector, async::Async< MatrixTensor > const &matrix, MatrixNorm kind)
Schedule a dense matrix norm returning a host C++ scalar through an explicit selector.
Definition async/matrix_norm.hpp:167
@ One
Induced one-norm: largest column sum of entry magnitudes.
MatrixRegion
Matrix region selected by structured initialization operations.
Definition operation_tags.hpp:208
constexpr detail::scalar_math::abs_fn abs
Absolute value or complex magnitude, preserving the selected scalar implementation.
Definition math.hpp:459
Definition async/async.hpp:26
constexpr auto abs(basic_half_int< T > value) -> basic_half_int< T >
Return the absolute value of a half-integer.
Definition half_int.hpp:431
mpreal norm(mpcomplex const &z)
Definition mpcomplex.hpp:494
void fill(BackendSelector selector, async::Async< OutputTensor > &output, Value &&value)
Fill an existing async Tensor without reading its old values.
Definition linalg/async/transform.hpp:205
void scale(Tensor &tensor, Scalar factor)
Multiply every stored numerical block by a scalar in place.
Definition block_tensor_linear.hpp:400
std::ptrdiff_t index_type
Definition types.hpp:19
mpreal beta(mpreal const &a, mpreal const &x)
Real Beta function; positive rational/integer pairs retain exact values.
Definition mpreal_special.hpp:164
Eigenvalues and optional eigenvectors of a dense complex Hermitian matrix.
Definition dense_subspace_unused.hpp:32
std::vector< Real > eigenvalues
Definition dense_subspace_unused.hpp:33
detail::ColumnMajorLapackMatrix< uni20::complex< Real > > eigenvectors
Definition dense_subspace_unused.hpp:34
Compact Householder bidiagonal reduction of a dense real matrix.
Definition dense_subspace_unused.hpp:393
std::vector< Scalar > taup
Definition dense_subspace_unused.hpp:399
bool upper
Definition dense_subspace_unused.hpp:400
detail::ColumnMajorLapackMatrix< Scalar > bidiagonal
Definition dense_subspace_unused.hpp:394
std::vector< Scalar > offdiagonal
Definition dense_subspace_unused.hpp:397
std::vector< Scalar > tauq
Definition dense_subspace_unused.hpp:398
std::vector< Scalar > diagonal
Definition dense_subspace_unused.hpp:396
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:395
Singular value decomposition of a real bidiagonal matrix.
Definition dense_subspace_unused.hpp:406
detail::ColumnMajorLapackMatrix< Scalar > vt
Definition dense_subspace_unused.hpp:409
std::vector< Scalar > singular_values
Definition dense_subspace_unused.hpp:407
detail::ColumnMajorLapackMatrix< Scalar > u
Definition dense_subspace_unused.hpp:408
Compact Householder LQ factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:366
std::vector< Scalar > tau
Definition dense_subspace_unused.hpp:368
std::size_t rank
Definition dense_subspace_unused.hpp:369
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:367
Compact Householder QL factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:375
std::size_t rank
Definition dense_subspace_unused.hpp:378
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:376
std::vector< Scalar > tau
Definition dense_subspace_unused.hpp:377
Compact Householder QR factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:357
std::size_t rank
Definition dense_subspace_unused.hpp:360
std::vector< Scalar > tau
Definition dense_subspace_unused.hpp:359
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:358
Compact Householder RQ factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:384
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:385
std::size_t rank
Definition dense_subspace_unused.hpp:387
std::vector< Scalar > tau
Definition dense_subspace_unused.hpp:386
Dense real general matrix equilibration factors.
Definition dense_subspace_unused.hpp:153
Scalar row_condition
Definition dense_subspace_unused.hpp:156
Scalar max_abs
Definition dense_subspace_unused.hpp:158
std::vector< Scalar > row_scale
Definition dense_subspace_unused.hpp:154
Scalar column_condition
Definition dense_subspace_unused.hpp:157
std::vector< Scalar > column_scale
Definition dense_subspace_unused.hpp:155
Expert dense real linear solve result.
Definition dense_subspace_unused.hpp:130
char equilibration
Definition dense_subspace_unused.hpp:137
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:131
std::vector< std::size_t > pivot_rows
Definition dense_subspace_unused.hpp:133
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:134
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:138
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:136
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:135
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:132
Expert real general-band linear solve result.
Definition dense_subspace_unused.hpp:116
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:124
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:120
RealGeneralBandMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:118
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:121
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:117
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:122
std::vector< std::size_t > pivot_rows
Definition dense_subspace_unused.hpp:119
char equilibration
Definition dense_subspace_unused.hpp:123
LU factorization of a real square general band matrix.
Definition dense_subspace_unused.hpp:71
RealGeneralBandMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:72
std::vector< std::size_t > pivot_rows
Definition dense_subspace_unused.hpp:73
LAPACK general band storage for a real square matrix.
Definition dense_subspace_unused.hpp:61
detail::ColumnMajorLapackMatrix< Scalar > storage
Definition dense_subspace_unused.hpp:62
std::size_t upper_bandwidth
Definition dense_subspace_unused.hpp:65
std::size_t lower_bandwidth
Definition dense_subspace_unused.hpp:64
std::size_t order
Definition dense_subspace_unused.hpp:63
Expert real general-tridiagonal linear solve result.
Definition dense_subspace_unused.hpp:104
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:108
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:109
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:107
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:110
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:105
RealGeneralTridiagonalFactorization< Scalar > factorization
Definition dense_subspace_unused.hpp:106
LU factorization of a real square general tridiagonal matrix.
Definition dense_subspace_unused.hpp:95
RealGeneralTridiagonalMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:96
std::vector< std::size_t > pivot_rows
Definition dense_subspace_unused.hpp:98
std::vector< Scalar > second_upper_diagonal
Definition dense_subspace_unused.hpp:97
LAPACK general tridiagonal storage for a real square matrix.
Definition dense_subspace_unused.hpp:81
std::vector< Scalar > lower_diagonal
Definition dense_subspace_unused.hpp:82
std::vector< Scalar > diagonal
Definition dense_subspace_unused.hpp:83
std::vector< Scalar > upper_diagonal
Definition dense_subspace_unused.hpp:84
std::size_t order() const noexcept
Definition dense_subspace_unused.hpp:86
Generalized Hessenberg reduction of a dense real matrix pencil.
Definition dense_subspace_unused.hpp:521
detail::ColumnMajorLapackMatrix< Real > matrix_hessenberg_form
Definition dense_subspace_unused.hpp:522
detail::ColumnMajorLapackMatrix< Real > metric_triangular_form
Definition dense_subspace_unused.hpp:523
detail::ColumnMajorLapackMatrix< Real > left_orthogonal_vectors
Definition dense_subspace_unused.hpp:524
detail::ColumnMajorLapackMatrix< Real > right_orthogonal_vectors
Definition dense_subspace_unused.hpp:525
std::size_t first
Definition dense_subspace_unused.hpp:526
std::size_t last_exclusive
Definition dense_subspace_unused.hpp:527
Balanced dense real nonsymmetric matrix pencil and LAPACK scaling metadata.
Definition dense_subspace_unused.hpp:509
std::size_t balanced_last_exclusive
Definition dense_subspace_unused.hpp:515
std::vector< Real > right_scale
Definition dense_subspace_unused.hpp:513
detail::ColumnMajorLapackMatrix< Real > balanced_metric
Definition dense_subspace_unused.hpp:511
std::size_t balanced_first
Definition dense_subspace_unused.hpp:514
std::vector< Real > left_scale
Definition dense_subspace_unused.hpp:512
detail::ColumnMajorLapackMatrix< Real > balanced_matrix
Definition dense_subspace_unused.hpp:510
Eigenvalues and optional right eigenvectors of a real nonsymmetric matrix pencil.
Definition dense_subspace_unused.hpp:481
detail::ColumnMajorLapackMatrix< uni20::complex< Real > > right_eigenvectors
Definition dense_subspace_unused.hpp:485
std::vector< uni20::complex< Real > > alpha
Definition dense_subspace_unused.hpp:482
std::vector< Real > beta
Definition dense_subspace_unused.hpp:483
std::vector< uni20::complex< Real > > eigenvalues
Definition dense_subspace_unused.hpp:484
Expert eigensystem diagnostics for a dense real nonsymmetric matrix pencil.
Definition dense_subspace_unused.hpp:491
std::size_t balanced_last_exclusive
Definition dense_subspace_unused.hpp:503
std::vector< Real > right_balance_scale
Definition dense_subspace_unused.hpp:499
std::vector< Real > reciprocal_eigenvalue_condition_numbers
Definition dense_subspace_unused.hpp:496
Real balanced_matrix_norm
Definition dense_subspace_unused.hpp:500
std::vector< Real > beta
Definition dense_subspace_unused.hpp:493
std::vector< uni20::complex< Real > > eigenvalues
Definition dense_subspace_unused.hpp:494
std::size_t balanced_first
Definition dense_subspace_unused.hpp:502
std::vector< uni20::complex< Real > > alpha
Definition dense_subspace_unused.hpp:492
Real balanced_metric_norm
Definition dense_subspace_unused.hpp:501
std::vector< Real > left_balance_scale
Definition dense_subspace_unused.hpp:498
std::vector< Real > reciprocal_eigenvector_condition_numbers
Definition dense_subspace_unused.hpp:497
detail::ColumnMajorLapackMatrix< uni20::complex< Real > > right_eigenvectors
Definition dense_subspace_unused.hpp:495
Reciprocal condition estimates for eigenpairs of a generalized real Schur form.
Definition dense_subspace_unused.hpp:569
std::vector< Real > reciprocal_eigenvalue_condition_numbers
Definition dense_subspace_unused.hpp:570
std::vector< Real > reciprocal_eigenvector_condition_numbers
Definition dense_subspace_unused.hpp:571
std::size_t computed_estimates
Definition dense_subspace_unused.hpp:572
One diagonal block of a real Schur form.
Definition dense_subspace_unused.hpp:534
std::size_t selected_dimension
Definition dense_subspace_unused.hpp:543
std::vector< Real > beta
Definition dense_subspace_unused.hpp:540
std::vector< uni20::complex< Real > > alpha
Definition dense_subspace_unused.hpp:539
detail::ColumnMajorLapackMatrix< Real > metric_schur_form
Definition dense_subspace_unused.hpp:536
detail::ColumnMajorLapackMatrix< Real > right_schur_vectors
Definition dense_subspace_unused.hpp:538
detail::ColumnMajorLapackMatrix< Real > left_schur_vectors
Definition dense_subspace_unused.hpp:537
std::vector< uni20::complex< Real > > eigenvalues
Definition dense_subspace_unused.hpp:541
std::vector< RealSchurBlock< Real > > blocks
Definition dense_subspace_unused.hpp:542
detail::ColumnMajorLapackMatrix< Real > matrix_schur_form
Definition dense_subspace_unused.hpp:535
Right eigenvectors of a generalized real Schur form unpacked into complex columns.
Definition dense_subspace_unused.hpp:561
detail::ColumnMajorLapackMatrix< uni20::complex< Real > > right_eigenvectors
Definition dense_subspace_unused.hpp:562
std::size_t computed_vectors
Definition dense_subspace_unused.hpp:563
Selected generalized real Schur subspace with LAPACK tgsen diagnostics.
Definition dense_subspace_unused.hpp:549
std::size_t selected_dimension
Definition dense_subspace_unused.hpp:551
Real left_projection_lower_bound
Definition dense_subspace_unused.hpp:552
RealGeneralizedSchurDecomposition< Real > decomposition
Definition dense_subspace_unused.hpp:550
Real lower_deflating_subspace_separation
Definition dense_subspace_unused.hpp:555
Real upper_deflating_subspace_separation
Definition dense_subspace_unused.hpp:554
Real right_projection_lower_bound
Definition dense_subspace_unused.hpp:553
Compact real Hessenberg reduction of a dense square matrix.
Definition dense_subspace_unused.hpp:415
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:417
std::size_t last_exclusive
Definition dense_subspace_unused.hpp:420
std::size_t first
Definition dense_subspace_unused.hpp:419
detail::ColumnMajorLapackMatrix< Scalar > hessenberg
Definition dense_subspace_unused.hpp:416
std::vector< Scalar > tau
Definition dense_subspace_unused.hpp:418
Reduced LQ factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:333
detail::ColumnMajorLapackMatrix< Scalar > q
Definition dense_subspace_unused.hpp:335
detail::ColumnMajorLapackMatrix< Scalar > l
Definition dense_subspace_unused.hpp:334
LU factorization of a dense real square matrix.
Definition dense_subspace_unused.hpp:49
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:50
std::vector< std::size_t > pivot_rows
Definition dense_subspace_unused.hpp:51
Balanced dense real nonsymmetric matrix and LAPACK scaling metadata.
Definition dense_subspace_unused.hpp:471
detail::ColumnMajorLapackMatrix< Real > balanced_matrix
Definition dense_subspace_unused.hpp:472
std::size_t balanced_first
Definition dense_subspace_unused.hpp:474
std::vector< Real > scale
Definition dense_subspace_unused.hpp:473
std::size_t balanced_last_exclusive
Definition dense_subspace_unused.hpp:475
Eigenvalues and optional right eigenvectors of a real nonsymmetric matrix.
Definition dense_subspace_unused.hpp:448
std::size_t balanced_first
Definition dense_subspace_unused.hpp:455
std::vector< Real > reciprocal_eigenvalue_condition_numbers
Definition dense_subspace_unused.hpp:451
std::vector< uni20::complex< Real > > eigenvalues
Definition dense_subspace_unused.hpp:449
detail::ColumnMajorLapackMatrix< uni20::complex< Real > > right_eigenvectors
Definition dense_subspace_unused.hpp:450
std::size_t balanced_last_exclusive
Definition dense_subspace_unused.hpp:456
std::vector< Real > balance_scale
Definition dense_subspace_unused.hpp:453
Real balanced_matrix_norm
Definition dense_subspace_unused.hpp:454
std::vector< Real > reciprocal_eigenvector_condition_numbers
Definition dense_subspace_unused.hpp:452
Pivoted Cholesky factorization of a dense real positive semidefinite matrix.
Definition dense_subspace_unused.hpp:265
MatrixFill triangle
Definition dense_subspace_unused.hpp:269
std::vector< std::size_t > pivot_order
Definition dense_subspace_unused.hpp:267
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:266
bool rank_deficient
Definition dense_subspace_unused.hpp:270
std::size_t rank
Definition dense_subspace_unused.hpp:268
Reduced QR factorization with column pivoting of a dense real matrix.
Definition dense_subspace_unused.hpp:438
detail::ColumnMajorLapackMatrix< Scalar > q
Definition dense_subspace_unused.hpp:439
detail::ColumnMajorLapackMatrix< Scalar > r
Definition dense_subspace_unused.hpp:440
std::vector< std::size_t > pivot_columns
Definition dense_subspace_unused.hpp:441
Reduced QL factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:341
detail::ColumnMajorLapackMatrix< Scalar > l
Definition dense_subspace_unused.hpp:343
detail::ColumnMajorLapackMatrix< Scalar > q
Definition dense_subspace_unused.hpp:342
Reduced QR factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:325
detail::ColumnMajorLapackMatrix< Scalar > r
Definition dense_subspace_unused.hpp:327
detail::ColumnMajorLapackMatrix< Scalar > q
Definition dense_subspace_unused.hpp:326
Rank-revealing dense real least-squares result.
Definition dense_subspace_unused.hpp:298
std::size_t rank
Definition dense_subspace_unused.hpp:300
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:299
std::vector< std::size_t > pivot_columns
Definition dense_subspace_unused.hpp:301
Dense real refined linear solve result.
Definition dense_subspace_unused.hpp:144
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:146
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:145
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:147
Reduced RQ factorization of a dense real matrix.
Definition dense_subspace_unused.hpp:349
detail::ColumnMajorLapackMatrix< Scalar > q
Definition dense_subspace_unused.hpp:351
detail::ColumnMajorLapackMatrix< Scalar > r
Definition dense_subspace_unused.hpp:350
Reciprocal condition estimates for eigenpairs of a real Schur form.
Definition dense_subspace_unused.hpp:597
std::vector< Scalar > reciprocal_eigenvalue_condition_numbers
Definition dense_subspace_unused.hpp:598
std::vector< Scalar > reciprocal_eigenvector_condition_numbers
Definition dense_subspace_unused.hpp:599
std::size_t computed_estimates
Definition dense_subspace_unused.hpp:600
Definition dense_subspace.hpp:73
uni20::DenseMatrix< Scalar > schur_form
Definition dense_subspace.hpp:74
std::vector< uni20::complex< Scalar > > eigenvalues
Definition dense_subspace.hpp:76
uni20::DenseMatrix< Scalar > schur_vectors
Definition dense_subspace.hpp:75
std::vector< RealSchurBlock< Scalar > > blocks
Definition dense_subspace.hpp:77
Right eigenvectors of a real Schur form unpacked into complex columns.
Definition dense_subspace_unused.hpp:589
std::size_t computed_vectors
Definition dense_subspace_unused.hpp:591
detail::ColumnMajorLapackMatrix< uni20::complex< Scalar > > right_eigenvectors
Definition dense_subspace_unused.hpp:590
Eigenvalues and optional right eigenvectors of a complex nonsymmetric matrix.
Definition dense_subspace_unused.hpp:579
Scalar reciprocal_invariant_subspace_condition
Definition dense_subspace_unused.hpp:583
RealSchurDecomposition< Scalar > decomposition
Definition dense_subspace_unused.hpp:580
Scalar reciprocal_eigenvalue_cluster_condition
Definition dense_subspace_unused.hpp:582
std::size_t selected_dimension
Definition dense_subspace_unused.hpp:581
Singular values and optional singular vectors of a dense real matrix.
Definition dense_subspace_unused.hpp:40
detail::ColumnMajorLapackMatrix< Scalar > left_singular_vectors
Definition dense_subspace_unused.hpp:42
detail::ColumnMajorLapackMatrix< Scalar > right_singular_vectors_transpose
Definition dense_subspace_unused.hpp:43
std::vector< Scalar > singular_values
Definition dense_subspace_unused.hpp:41
SVD-based dense real least-squares result.
Definition dense_subspace_unused.hpp:307
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:308
std::size_t rank
Definition dense_subspace_unused.hpp:309
std::vector< Scalar > singular_values
Definition dense_subspace_unused.hpp:310
Dense real Sylvester equation result.
Definition dense_subspace_unused.hpp:316
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:317
bool separation_perturbed
Definition dense_subspace_unused.hpp:319
Scalar scale
Definition dense_subspace_unused.hpp:318
Definition dense_subspace_unused.hpp:24
std::vector< Scalar > eigenvalues
Definition dense_subspace_unused.hpp:25
detail::ColumnMajorLapackMatrix< Scalar > eigenvectors
Definition dense_subspace_unused.hpp:26
Expert dense real symmetric-indefinite linear solve result.
Definition dense_subspace_unused.hpp:285
std::vector< int > pivot_blocks
Definition dense_subspace_unused.hpp:288
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:286
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:292
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:290
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:289
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:287
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:291
Bunch-Kaufman factorization of a dense real symmetric-indefinite matrix.
Definition dense_subspace_unused.hpp:276
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:277
std::vector< int > pivot_blocks
Definition dense_subspace_unused.hpp:278
MatrixFill triangle
Definition dense_subspace_unused.hpp:279
Expert real SPD band linear solve result.
Definition dense_subspace_unused.hpp:216
char equilibration
Definition dense_subspace_unused.hpp:223
RealSymmetricPositiveDefiniteBandFactorization< Scalar > factorization
Definition dense_subspace_unused.hpp:218
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:224
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:221
std::vector< Scalar > scale
Definition dense_subspace_unused.hpp:222
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:219
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:217
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:220
Cholesky factorization of a real SPD band matrix.
Definition dense_subspace_unused.hpp:209
RealSymmetricPositiveDefiniteBandMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:210
LAPACK symmetric positive-definite band storage for a real square matrix.
Definition dense_subspace_unused.hpp:199
detail::ColumnMajorLapackMatrix< Scalar > storage
Definition dense_subspace_unused.hpp:200
std::size_t order
Definition dense_subspace_unused.hpp:201
std::size_t bandwidth
Definition dense_subspace_unused.hpp:202
MatrixFill triangle
Definition dense_subspace_unused.hpp:203
Dense real SPD equilibration factors.
Definition dense_subspace_unused.hpp:178
Scalar max_abs
Definition dense_subspace_unused.hpp:181
std::vector< Scalar > scale
Definition dense_subspace_unused.hpp:179
Scalar scale_condition
Definition dense_subspace_unused.hpp:180
Expert dense real SPD linear solve result.
Definition dense_subspace_unused.hpp:164
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:169
char equilibration
Definition dense_subspace_unused.hpp:171
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:168
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:165
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:167
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:166
std::vector< Scalar > scale
Definition dense_subspace_unused.hpp:170
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:172
Cholesky factorization of a dense real SPD matrix.
Definition dense_subspace_unused.hpp:187
detail::ColumnMajorLapackMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:188
MatrixFill triangle
Definition dense_subspace_unused.hpp:189
Expert real SPD tridiagonal linear solve result.
Definition dense_subspace_unused.hpp:253
Scalar reciprocal_condition
Definition dense_subspace_unused.hpp:256
bool reciprocal_condition_below_machine_precision
Definition dense_subspace_unused.hpp:259
RealSymmetricPositiveDefiniteTridiagonalFactorization< Scalar > factorization
Definition dense_subspace_unused.hpp:255
std::vector< Scalar > backward_error_bounds
Definition dense_subspace_unused.hpp:258
std::vector< Scalar > forward_error_bounds
Definition dense_subspace_unused.hpp:257
detail::ColumnMajorLapackMatrix< Scalar > solution
Definition dense_subspace_unused.hpp:254
Cholesky factorization of a real SPD tridiagonal matrix.
Definition dense_subspace_unused.hpp:246
RealSymmetricPositiveDefiniteTridiagonalMatrix< Scalar > factors
Definition dense_subspace_unused.hpp:247
Real symmetric positive-definite tridiagonal matrix storage.
Definition dense_subspace_unused.hpp:233
std::vector< Scalar > diagonal
Definition dense_subspace_unused.hpp:234
std::vector< Scalar > offdiagonal
Definition dense_subspace_unused.hpp:235
std::size_t order() const noexcept
Definition dense_subspace_unused.hpp:237
Compact real symmetric tridiagonal reduction of a dense symmetric matrix.
Definition dense_subspace_unused.hpp:426
std::vector< Scalar > tau
Definition dense_subspace_unused.hpp:431
std::vector< Scalar > offdiagonal
Definition dense_subspace_unused.hpp:430
MatrixFill triangle
Definition dense_subspace_unused.hpp:432
detail::ColumnMajorLapackMatrix< Scalar > reflectors
Definition dense_subspace_unused.hpp:428
detail::ColumnMajorLapackMatrix< Scalar > tridiagonal
Definition dense_subspace_unused.hpp:427
std::vector< Scalar > diagonal
Definition dense_subspace_unused.hpp:429
Eigenvalues and optional eigenvectors of a symmetric tridiagonal matrix.
Definition dense_subspace.hpp:22
std::vector< Scalar > eigenvalues
Definition dense_subspace.hpp:23
uni20::DenseMatrix< Scalar > eigenvectors
Definition dense_subspace.hpp:24
Project-level numeric limits customization point.
Definition numeric_limits.hpp:16