LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
exact_matrix.cpp
浏览该文件的文档.
3
4#include <algorithm>
5#include <limits>
6#include <new>
7#include <set>
8
9namespace LMCAS::detail {
10using namespace matrix_kernel;
11namespace {
12void subtract_pivot_row(ExactMatrixData& matrix, std::size_t row,
13 std::size_t pivot_row, const ExprPtr& factor, ComputationContext& context) {
14 for (std::size_t target = 0; target < matrix.cols; ++target) {
15 matrix.at(row, target) = exact_subtract(
16 matrix.at(row, target),
17 exact_multiply(factor, matrix.at(pivot_row, target), context), context);
18 }
19}
20
21Result<void> eliminate_below(ExactMatrixData& matrix, std::size_t pivot_row,
22 std::size_t column, const ExprPtr& pivot_value,
24 const std::string& operation) {
25 for (std::size_t row = pivot_row + 1; row < matrix.rows; ++row) {
26 auto proof = classify_exact_zero(matrix.at(row, column), context, operation);
27 if (!proof) return Result<void>::failure(proof.error());
28 if (proof.value() == ZeroProof::Zero) continue;
29 auto factor = exact_divide(matrix.at(row, column), pivot_value, context);
30 subtract_pivot_row(matrix, row, pivot_row, factor, context);
31 }
32 return Result<void>::success();
33}
34
36 const std::string& operation) {
37 for (std::size_t pivot_index = result.rank; pivot_index-- > 0;) {
38 const std::size_t row = pivot_index;
39 const std::size_t column = result.pivot_columns[pivot_index];
40 auto pivot_value = simplify_expr(result.matrix.at(row, column), context);
41 for (std::size_t target = 0; target < result.matrix.cols; ++target) {
42 result.matrix.at(row, target) = exact_divide(
43 result.matrix.at(row, target), pivot_value, context);
44 }
45 for (std::size_t upper = 0; upper < row; ++upper) {
46 auto proof = classify_exact_zero(
47 result.matrix.at(upper, column), context, operation);
48 if (!proof) return Result<void>::failure(proof.error());
49 if (proof.value() == ZeroProof::Zero) continue;
50 auto factor = result.matrix.at(upper, column);
51 subtract_pivot_row(result.matrix, upper, row, factor, context);
52 }
53 }
54 return Result<void>::success();
55}
56}
57
58namespace {
60 EliminationResult& result, std::size_t coefficient_columns,
61 ComputationContext& context, const std::string& operation) {
62 std::size_t pivot_row = 0;
63 for (std::size_t column = 0;
64 column < coefficient_columns && pivot_row < result.matrix.rows;
65 ++column) {
66 auto pivot = choose_pivot(
67 result.matrix, pivot_row, column, context, operation);
68 if (!pivot) return Result<void>::failure(pivot.error());
69 if (!pivot.value()) continue;
70 if (*pivot.value() != pivot_row) {
71 swap_rows(result.matrix, *pivot.value(), pivot_row);
72 ++result.row_swaps;
73 }
74 auto pivot_value = simplify_expr(result.matrix.at(pivot_row, column), context);
75 result.pivot_columns.push_back(column);
76 result.pivot_values.push_back(pivot_value);
77 auto reduced = eliminate_below(
78 result.matrix, pivot_row, column, pivot_value, context, operation);
79 if (!reduced) return Result<void>::failure(reduced.error());
80 ++pivot_row;
81 }
82 result.rank = result.pivot_columns.size();
83 return Result<void>::success();
84}
85}
86
88 ExactMatrixData input,
89 std::size_t coefficient_columns,
90 EliminationForm form,
92 const std::string& operation) {
93 auto valid = validate_matrix(input, operation);
94 if (!valid) return Result<EliminationResult>::failure(valid.error());
95 if (coefficient_columns == 0 || coefficient_columns > input.cols) {
98 "coefficient column count is outside matrix shape", operation);
99 }
100 try {
101 EliminationResult result;
102 result.matrix = std::move(input);
103 auto forward = eliminate_forward(result, coefficient_columns, context, operation);
104 if (!forward) return Result<EliminationResult>::failure(forward.error());
105
107 auto reduced = reduce_above(result, context, operation);
108 if (!reduced) return Result<EliminationResult>::failure(reduced.error());
109 }
110 return Result<EliminationResult>::success(std::move(result));
111 } catch (const std::bad_alloc&) {
114 "exact elimination allocation failed", operation);
115 } catch (const std::exception& error) {
118 }
119}
120
122 ExactMatrixData input,
123 std::size_t coefficient_columns,
125 const std::string& operation) {
126 auto eliminated = eliminate_exact(
127 std::move(input), coefficient_columns,
129 if (!eliminated) return Result<ExactMatrixData>::failure(eliminated.error());
131 std::move(eliminated.value().matrix));
132}
133
135 ExactMatrixData input,
136 std::size_t coefficient_columns,
138 const std::string& operation) {
139 auto eliminated = eliminate_exact(
140 std::move(input), coefficient_columns,
142 if (!eliminated) return Result<std::size_t>::failure(eliminated.error());
143 return Result<std::size_t>::success(eliminated.value().rank);
144}
145
147 const ExactMatrixData& input,
149 const std::string& operation) {
150 auto valid = validate_matrix(input, operation);
151 if (!valid) return Result<ExactMatrixData>::failure(valid.error());
152 if (input.rows != input.cols) {
155 "inverse requires a square matrix", operation);
156 }
157 const std::size_t n = input.rows;
158 ExactMatrixData augmented{n, 2 * n, {}};
159 augmented.entries.reserve(n * 2 * n);
160 for (std::size_t row = 0; row < n; ++row) {
161 for (std::size_t column = 0; column < n; ++column) {
162 augmented.entries.push_back(input.at(row, column));
163 }
164 for (std::size_t column = 0; column < n; ++column) {
165 augmented.entries.push_back(
166 SymbolicExpr::number(row == column ? 1 : 0));
167 }
168 }
169 auto eliminated = eliminate_exact(
170 std::move(augmented), n,
172 if (!eliminated) return Result<ExactMatrixData>::failure(eliminated.error());
173 if (eliminated.value().rank != n) {
176 "matrix is singular and has no inverse", operation);
177 }
178 ExactMatrixData inverse{n, n, {}};
179 inverse.entries.reserve(n * n);
180 for (std::size_t row = 0; row < n; ++row) {
181 for (std::size_t column = 0; column < n; ++column) {
182 inverse.entries.push_back(
183 eliminated.value().matrix.at(row, n + column));
184 }
185 }
186 return Result<ExactMatrixData>::success(std::move(inverse));
187}
188
189}
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
Result< void > reduce_above(EliminationResult &result, ComputationContext &context, const std::string &operation)
Result< void > eliminate_forward(EliminationResult &result, std::size_t coefficient_columns, ComputationContext &context, const std::string &operation)
void subtract_pivot_row(ExactMatrixData &matrix, std::size_t row, std::size_t pivot_row, const ExprPtr &factor, ComputationContext &context)
Result< void > eliminate_below(ExactMatrixData &matrix, std::size_t pivot_row, std::size_t column, const ExprPtr &pivot_value, ComputationContext &context, const std::string &operation)
ExprPtr simplify_expr(ExprPtr expression, ComputationContext &context)
Result< std::optional< std::size_t > > choose_pivot(const ExactMatrixData &matrix, std::size_t first_row, std::size_t column, ComputationContext &context, const std::string &operation)
ExprPtr exact_multiply(const ExprPtr &left, const ExprPtr &right, ComputationContext &context)
ExprPtr exact_subtract(const ExprPtr &left, const ExprPtr &right, ComputationContext &context)
void swap_rows(ExactMatrixData &matrix, std::size_t first, std::size_t second)
Result< void > validate_matrix(const ExactMatrixData &matrix, const std::string &operation)
ExprPtr exact_divide(const ExprPtr &numerator, const ExprPtr &denominator, ComputationContext &context)
多元 Hensel 提升(单变量步)
Result< EliminationResult > eliminate_exact(ExactMatrixData input, std::size_t coefficient_columns, EliminationForm form, ComputationContext &context, const std::string &operation)
Result< ZeroProof > classify_exact_zero(const ExprPtr &expression, ComputationContext &context, const std::string &operation)
std::vector< std::size_t > pivot_columns
Result< std::size_t > rank_exact(ExactMatrixData input, std::size_t coefficient_columns, ComputationContext &context, const std::string &operation)
ComputationContext const std::string & operation
std::size_t std::size_t ComputationContext & context
Result< ExactMatrixData > inverse_exact(const ExactMatrixData &input, ComputationContext &context, const std::string &operation)
Result< ExactMatrixData > rref_exact(ExactMatrixData input, std::size_t coefficient_columns, ComputationContext &context, const std::string &operation)
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
std::shared_ptr< SymbolicExpr > ExprPtr
const ExprPtr & target
const ExprPtr & at(std::size_t row, std::size_t col) const
内部 AST 定义。