LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
exact_rational_solve.cpp
浏览该文件的文档.
2
3#include <algorithm>
4
5namespace LMCAS::detail {
6namespace {
7
9 std::vector<Rational>& matrix, std::size_t rows, std::size_t columns,
10 std::size_t pivot_row, std::size_t column, std::size_t first_target) {
11 const Rational pivot = matrix[pivot_row * columns + column];
12 for (std::size_t target = first_target; target < columns; ++target) {
13 matrix[pivot_row * columns + target] =
14 matrix[pivot_row * columns + target] / pivot;
15 }
16 for (std::size_t row = 0; row < rows; ++row) {
17 if (row == pivot_row) continue;
18 const Rational factor = matrix[row * columns + column];
19 if (factor == Rational(0)) continue;
20 for (std::size_t target = first_target; target < columns; ++target) {
21 matrix[row * columns + target] =
22 matrix[row * columns + target] -
23 factor * matrix[pivot_row * columns + target];
24 }
25 }
26}
27
28}
29
30std::vector<std::optional<std::size_t>> reduce_rational_rows(
31 std::size_t rows, std::size_t coefficient_columns,
32 std::vector<Rational>& matrix, bool start_at_pivot) {
33 const std::size_t columns = coefficient_columns + 1;
34 std::vector<std::optional<std::size_t>> pivot_rows(coefficient_columns);
35 std::size_t pivot_row = 0;
36 for (std::size_t column = 0;
37 column < coefficient_columns && pivot_row < rows; ++column) {
38 std::size_t selected = pivot_row;
39 while (selected < rows &&
40 matrix[selected * columns + column] == Rational(0)) {
41 ++selected;
42 }
43 if (selected == rows) continue;
44 if (selected != pivot_row) {
45 for (std::size_t target = 0; target < columns; ++target) {
46 std::swap(matrix[selected * columns + target],
47 matrix[pivot_row * columns + target]);
48 }
49 }
50 reduce_rational_pivot(matrix, rows, columns, pivot_row, column,
51 start_at_pivot ? column : 0);
52 pivot_rows[column] = pivot_row++;
53 }
54 return pivot_rows;
55}
56
58 std::size_t rows, std::size_t coefficient_columns,
59 const std::vector<Rational>& matrix) {
60 const std::size_t columns = coefficient_columns + 1;
61 for (std::size_t row = 0; row < rows; ++row) {
62 bool zero = true;
63 for (std::size_t column = 0; column < coefficient_columns; ++column) {
64 zero = zero && matrix[row * columns + column] == Rational(0);
65 }
66 if (zero && matrix[row * columns + coefficient_columns] != Rational(0)) {
67 return true;
68 }
69 }
70 return false;
71}
72
74 std::size_t rows,
75 std::size_t coefficient_columns,
76 std::vector<Rational> matrix,
78 const std::string& operation) {
79 const std::size_t columns = coefficient_columns + 1;
80 if (rows == 0 || coefficient_columns == 0 ||
81 matrix.size() != rows * columns) {
82 return Result<std::vector<Rational>>::failure(
84 "rational linear-system storage is invalid", operation);
85 }
86 auto budget = context.consume_steps(rows * columns, operation);
87 if (!budget) return Result<std::vector<Rational>>::failure(budget.error());
88 auto pivot_rows = reduce_rational_rows(rows, coefficient_columns, matrix, true);
89 if (rational_system_inconsistent(rows, coefficient_columns, matrix)) {
90 return Result<std::vector<Rational>>::failure(
92 "rational linear system is inconsistent", operation);
93 }
94 std::vector<Rational> solution(coefficient_columns, Rational(0));
95 for (std::size_t column = 0; column < coefficient_columns; ++column) {
96 if (!pivot_rows[column]) {
97 return Result<std::vector<Rational>>::failure(
99 "rational linear system does not have a unique solution",
100 operation);
101 }
102 solution[column] =
103 matrix[*pivot_rows[column] * columns + coefficient_columns];
104 }
105 return Result<std::vector<Rational>>::success(std::move(solution));
106}
107
108}
void reduce_rational_pivot(std::vector< Rational > &matrix, std::size_t rows, std::size_t columns, std::size_t pivot_row, std::size_t column, std::size_t first_target)
多元 Hensel 提升(单变量步)
bool rational_system_inconsistent(std::size_t rows, std::size_t coefficient_columns, const std::vector< Rational > &matrix)
Result< std::vector< Rational > > solve_rational_unique(std::size_t rows, std::size_t coefficient_columns, std::vector< Rational > matrix, ComputationContext &context, const std::string &operation)
ComputationContext const std::string & operation
std::size_t std::size_t ComputationContext & context
std::vector< std::optional< std::size_t > > reduce_rational_rows(std::size_t rows, std::size_t coefficient_columns, std::vector< Rational > &matrix, bool start_at_pivot)
const ExprPtr & target