LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
exact_matrix_determinant.cpp
浏览该文件的文档.
1
#include "
internal/exact_matrix_support.hpp
"
2
#include "
internal/symbolic_ast.hpp
"
3
4
#include <algorithm>
5
#include <limits>
6
#include <new>
7
#include <set>
8
9
namespace
LMCAS::detail
{
10
using namespace
matrix_kernel
;
11
namespace
{
12
Result<ExprPtr>
rational_determinant
(
13
const
ExactMatrixData
& input,
14
ComputationContext
&
context
,
15
const
std::string&
operation
) {
16
std::vector<Rational> values;
17
values.reserve(input.
entries
.size());
18
for
(
const
auto
& entry : input.
entries
) {
19
auto
value
=
exact_rational
(entry);
20
if
(!
value
) {
21
return
Result<ExprPtr>::failure
(
22
CasErrc::Inconclusive
,
23
"matrix is not entirely rational"
,
24
operation
);
25
}
26
values.push_back(*
value
);
27
}
28
auto
determinant =
rational_determinant_value_impl
(
29
input.
rows
, std::move(values),
context
,
operation
);
30
if
(!determinant)
return
Result<ExprPtr>::failure
(determinant.error());
31
return
Result<ExprPtr>::success
(
32
SymbolicExpr::number(determinant.value()));
33
}
34
35
Result<ExprPtr>
determinant_cofactor
(
36
const
ExactMatrixData
& matrix,
37
ComputationContext
&
context
,
38
const
std::string&
operation
) {
39
auto
budget
=
context
.consume_steps(1,
operation
);
40
if
(!
budget
)
return
Result<ExprPtr>::failure
(
budget
.error());
41
if
(matrix.
rows
== 1) {
42
return
Result<ExprPtr>::success
(matrix.
entries
[0]);
43
}
44
auto
sum = SymbolicExpr::number(0);
45
for
(std::size_t column = 0; column < matrix.
cols
; ++column) {
46
if
(
auto
coefficient =
exact_rational
(matrix.
at
(0, column));
47
coefficient && *coefficient == Rational(0)) {
48
continue
;
49
}
50
ExactMatrixData
minor{
51
matrix.
rows
- 1, matrix.
cols
- 1, {}};
52
minor.
entries
.reserve(minor.
rows
* minor.
cols
);
53
for
(std::size_t row = 1; row < matrix.
rows
; ++row) {
54
for
(std::size_t source = 0; source < matrix.
cols
; ++source) {
55
if
(source != column) {
56
minor.
entries
.push_back(matrix.
at
(row, source));
57
}
58
}
59
}
60
auto
minor_determinant =
determinant_cofactor
(
61
minor,
context
,
operation
);
62
if
(!minor_determinant) {
63
return
Result<ExprPtr>::failure
(minor_determinant.error());
64
}
65
auto
term =
exact_multiply
(
66
matrix.
at
(0, column), minor_determinant.value(),
context
);
67
if
(column % 2 != 0) term =
exact_negate
(term,
context
);
68
sum =
exact_add
(sum, term,
context
);
69
}
70
return
Result<ExprPtr>::success
(
simplify_expr
(sum,
context
));
71
}
72
73
Result<ExprPtr>
symbolic_determinant_value
(
74
const
ExactMatrixData
& input,
ComputationContext
&
context
,
75
const
std::string&
operation
) {
76
ExactMatrixData
matrix = input;
77
const
std::size_t n = matrix.
rows
;
78
if
(n == 1)
return
Result<ExprPtr>::success
(matrix.
entries
[0]);
79
auto
previous = SymbolicExpr::number(1);
80
std::size_t swaps = 0;
81
for
(std::size_t column = 0; column + 1 < n; ++column) {
82
auto
pivot =
choose_pivot
(matrix, column, column,
context
,
operation
);
83
if
(!pivot) {
84
if
(pivot.error().code ==
CasErrc::Inconclusive
) {
85
return
determinant_cofactor
(input,
context
,
operation
);
86
}
87
return
Result<ExprPtr>::failure
(pivot.error());
88
}
89
if
(!pivot.value()) {
90
return
Result<ExprPtr>::success
(SymbolicExpr::number(0));
91
}
92
if
(*pivot.value() != column) {
93
swap_rows
(matrix, *pivot.value(), column);
94
++swaps;
95
}
96
auto
pivot_value = matrix.
at
(column, column);
97
for
(std::size_t row = column + 1; row < n; ++row) {
98
for
(std::size_t
target
= column + 1;
target
< n; ++
target
) {
99
auto
numerator =
exact_subtract
(
100
exact_multiply
(matrix.
at
(row,
target
), pivot_value,
context
),
101
exact_multiply
(matrix.
at
(row, column), matrix.
at
(column,
target
),
context
),
context
);
102
matrix.
at
(row,
target
) =
exact_divide
(numerator, previous,
context
);
103
}
104
matrix.
at
(row, column) = SymbolicExpr::number(0);
105
}
106
previous = pivot_value;
107
}
108
auto
determinant = matrix.
at
(n - 1, n - 1);
109
if
(swaps % 2 != 0) determinant =
exact_negate
(determinant,
context
);
110
return
Result<ExprPtr>::success
(
simplify_expr
(determinant,
context
));
111
}
112
113
}
114
115
Result<ExprPtr>
determinant_exact
(
116
const
ExactMatrixData
& input,
117
ComputationContext
&
context
,
118
const
std::string&
operation
) {
119
auto
valid =
validate_matrix
(input,
operation
);
120
if
(!valid)
return
Result<ExprPtr>::failure
(valid.error());
121
if
(input.
rows
!= input.
cols
) {
122
return
Result<ExprPtr>::failure
(
123
CasErrc::InvalidArgument
,
124
"determinant requires a square matrix"
,
operation
);
125
}
126
bool
all_rational =
true
;
127
for
(
const
auto
& entry : input.
entries
) {
128
all_rational = all_rational &&
exact_rational
(entry).has_value();
129
}
130
if
(all_rational)
return
rational_determinant(input,
context
,
operation
);
131
132
try
{
133
return
symbolic_determinant_value(input,
context
,
operation
);
134
}
catch
(
const
std::bad_alloc&) {
135
return
Result<ExprPtr>::failure
(
136
CasErrc::ResourceLimit
,
137
"exact determinant allocation failed"
,
operation
);
138
}
catch
(
const
std::exception& error) {
139
return
Result<ExprPtr>::failure
(
140
CasErrc::InternalInvariant
, error.what(),
operation
);
141
}
142
}
143
144
}
LMCAS::ComputationContext
定义
computation_context.hpp:99
LMCAS::Result
定义
result.hpp:39
LMCAS::Result::failure
static Result failure(CasErrc code, std::string message, std::string operation={})
定义
result.hpp:52
LMCAS::Result::success
static Result success(T value)
定义
result.hpp:48
exact_matrix_support.hpp
LMCAS::detail::anonymous_namespace{exact_matrix_determinant.cpp}::symbolic_determinant_value
Result< ExprPtr > symbolic_determinant_value(const ExactMatrixData &input, ComputationContext &context, const std::string &operation)
定义
exact_matrix_determinant.cpp:73
LMCAS::detail::anonymous_namespace{exact_matrix_determinant.cpp}::determinant_cofactor
Result< ExprPtr > determinant_cofactor(const ExactMatrixData &matrix, ComputationContext &context, const std::string &operation)
定义
exact_matrix_determinant.cpp:35
LMCAS::detail::anonymous_namespace{exact_matrix_determinant.cpp}::rational_determinant
Result< ExprPtr > rational_determinant(const ExactMatrixData &input, ComputationContext &context, const std::string &operation)
定义
exact_matrix_determinant.cpp:12
LMCAS::detail::matrix_kernel
定义
exact_matrix_support.cpp:11
LMCAS::detail::matrix_kernel::simplify_expr
ExprPtr simplify_expr(ExprPtr expression, ComputationContext &context)
定义
exact_matrix_support.cpp:43
LMCAS::detail::matrix_kernel::exact_rational
std::optional< Rational > exact_rational(const ExprPtr &expression)
定义
exact_matrix_support.cpp:36
LMCAS::detail::matrix_kernel::choose_pivot
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)
定义
exact_matrix_support.cpp:84
LMCAS::detail::matrix_kernel::exact_multiply
ExprPtr exact_multiply(const ExprPtr &left, const ExprPtr &right, ComputationContext &context)
定义
exact_matrix_support.cpp:67
LMCAS::detail::matrix_kernel::exact_subtract
ExprPtr exact_subtract(const ExprPtr &left, const ExprPtr &right, ComputationContext &context)
定义
exact_matrix_support.cpp:63
LMCAS::detail::matrix_kernel::exact_negate
ExprPtr exact_negate(const ExprPtr &expression, ComputationContext &context)
定义
exact_matrix_support.cpp:58
LMCAS::detail::matrix_kernel::swap_rows
void swap_rows(ExactMatrixData &matrix, std::size_t first, std::size_t second)
定义
exact_matrix_support.cpp:75
LMCAS::detail::matrix_kernel::validate_matrix
Result< void > validate_matrix(const ExactMatrixData &matrix, const std::string &operation)
定义
exact_matrix_support.cpp:12
LMCAS::detail::matrix_kernel::exact_add
ExprPtr exact_add(const ExprPtr &left, const ExprPtr &right, ComputationContext &context)
定义
exact_matrix_support.cpp:54
LMCAS::detail::matrix_kernel::exact_divide
ExprPtr exact_divide(const ExprPtr &numerator, const ExprPtr &denominator, ComputationContext &context)
定义
exact_matrix_support.cpp:71
LMCAS::detail
多元 Hensel 提升(单变量步)
定义
assumption_context.hpp:31
LMCAS::detail::determinant_exact
Result< ExprPtr > determinant_exact(const ExactMatrixData &input, ComputationContext &context, const std::string &operation)
定义
exact_matrix_determinant.cpp:115
LMCAS::detail::rational_determinant_value_impl
Result< Rational > rational_determinant_value_impl(std::size_t dimension, std::vector< Rational > values, ComputationContext &context, const std::string &operation)
定义
exact_rational_determinant.cpp:8
LMCAS::detail::operation
ComputationContext const std::string & operation
定义
exact_algebraic.hpp:32
LMCAS::detail::budget
RewriteBudget & budget
定义
expression_transform.hpp:16
LMCAS::detail::context
std::size_t std::size_t ComputationContext & context
定义
exact_algebraic.hpp:27
LMCAS::CasErrc::Inconclusive
@ Inconclusive
定义
result.hpp:24
LMCAS::CasErrc::InvalidArgument
@ InvalidArgument
定义
result.hpp:13
LMCAS::CasErrc::InternalInvariant
@ InternalInvariant
定义
result.hpp:28
LMCAS::CasErrc::ResourceLimit
@ ResourceLimit
定义
result.hpp:25
LMCAS::target
const ExprPtr & target
定义
expr.hpp:317
LMCAS::value
const std::string const ExprPtr & value
定义
expr.hpp:293
LMCAS::detail::ExactMatrixData
定义
exact_matrix.hpp:26
LMCAS::detail::ExactMatrixData::rows
std::size_t rows
定义
exact_matrix.hpp:27
LMCAS::detail::ExactMatrixData::at
const ExprPtr & at(std::size_t row, std::size_t col) const
定义
exact_matrix.hpp:31
LMCAS::detail::ExactMatrixData::cols
std::size_t cols
定义
exact_matrix.hpp:28
LMCAS::detail::ExactMatrixData::entries
std::vector< ExprPtr > entries
定义
exact_matrix.hpp:29
symbolic_ast.hpp
内部 AST 定义。
src
exact_matrix_determinant.cpp
生成于
, 为 LMCAS使用
1.18.0