LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
matrix_decomposition_lu.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <new>
5
6namespace LMCAS {
7using namespace detail::matrix_decomposition;
8namespace {
9using RationalRows = std::vector<std::vector<Rational>>;
10
12 std::size_t column) {
13 const std::size_t n = upper.size();
14 for (std::size_t row = column + 1; row < n; ++row) {
15 const Rational multiplier =
16 upper[row][column] / upper[column][column];
17 lower[row][column] = multiplier;
18 for (std::size_t col = column; col < n; ++col) {
19 upper[row][col] =
20 upper[row][col] -
21 multiplier * upper[column][col];
22 }
23 }
24}
25
27 RationalRows& permutation, const std::string& operation) {
28 const std::size_t n = upper.size();
29 for (std::size_t i = 0; i < n; ++i) {
30 lower[i][i] = Rational(1);
31 permutation[i][i] = Rational(1);
32 }
33 for (std::size_t column = 0; column < n; ++column) {
34 std::size_t pivot = column;
35 while (pivot < n && upper[pivot][column] == Rational(0)) ++pivot;
36 if (pivot == n) {
39 "PLU decomposition requires a nonsingular matrix",
40 operation);
41 }
42 if (pivot != column) {
43 std::swap(upper[pivot], upper[column]);
44 std::swap(permutation[pivot], permutation[column]);
45 for (std::size_t prior = 0; prior < column; ++prior) {
46 std::swap(lower[pivot][prior], lower[column][prior]);
47 }
48 }
50 }
51 return Result<void>::success();
52}
53
54std::shared_ptr<SymbolicExpr> rational_rows_expression(const RationalRows& input) {
55 const std::size_t n = input.size();
56 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> grid(
57 n, std::vector<std::shared_ptr<SymbolicExpr>>(n));
58 for (std::size_t row = 0; row < n; ++row) {
59 for (std::size_t col = 0; col < n; ++col) {
60 grid[row][col] = exact_number_expr(input[row][col]);
61 }
62 }
63 return SymbolicExpr::matrix(grid);
64}
65}
66
68 const std::shared_ptr<SymbolicExpr>& A,
70{
71 const std::string operation = "lu_decomposition";
72 auto matrix = validate_decomposition_matrix(A, true, context, operation);
73 if (!matrix) return LUDecompositionResult::failure(matrix.error());
74 auto budget = context.consume_steps(matrix.value()->rows() * matrix.value()->cols() * 8 + 8,
75 operation);
76 if (!budget) return LUDecompositionResult::failure(budget.error());
77 auto values = exact_rational_matrix(matrix.value(), context);
78 if (!values) {
81 "exact PLU requires a rational matrix or proved symbolic pivots",
82 operation);
83 }
84 try {
85 const std::size_t n = values->size();
86 auto U_values = *values;
87 std::vector<std::vector<Rational>> L_values(
88 n, std::vector<Rational>(n, Rational(0)));
89 std::vector<std::vector<Rational>> P_values(
90 n, std::vector<Rational>(n, Rational(0)));
91 auto factored = factor_lu(L_values, U_values, P_values, operation);
92 if (!factored) return LUDecompositionResult::failure(factored.error());
94 rational_rows_expression(P_values),
95 rational_rows_expression(L_values),
96 rational_rows_expression(U_values)});
97 } catch (const std::bad_alloc&) {
99 "allocation failed while calculating LU decomposition",
100 operation);
101 } catch (const std::exception& ex) {
103 ex.what(),
104 operation);
105 }
106}
108 const std::shared_ptr<SymbolicExpr>& A)
109{
112}
113
114}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< void > factor_lu(RationalRows &lower, RationalRows &upper, RationalRows &permutation, const std::string &operation)
std::shared_ptr< SymbolicExpr > rational_rows_expression(const RationalRows &input)
void eliminate_lu_column(RationalRows &lower, RationalRows &upper, std::size_t column)
std::shared_ptr< SymbolicExpr > exact_number_expr(const Rational &value)
Result< std::shared_ptr< const MatrixNode > > validate_decomposition_matrix(const std::shared_ptr< SymbolicExpr > &A, bool require_square, ComputationContext &context, const std::string &operation)
std::optional< std::vector< std::vector< Rational > > > exact_rational_matrix(const std::shared_ptr< const MatrixNode > &matrix, ComputationContext &context)
Result< LUDecomposition > LUDecompositionResult
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
const ExprPtr & lower
LUDecompositionResult lu_decomposition_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)