LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
matrix_decomposition_cholesky.cpp
浏览该文件的文档.
1
#include "
internal/matrix_decomposition_support.hpp
"
2
#include "
internal/exact_rational_matrix.hpp
"
3
4
#include <algorithm>
5
#include <new>
6
7
namespace
LMCAS
{
8
using namespace
detail::matrix_decomposition
;
9
namespace
{
10
Result<void>
prove_exact_spd
(
11
const
std::shared_ptr<const MatrixNode>& matrix,
12
ComputationContext
&
context
,
13
const
std::string& operation) {
14
auto
values =
exact_rational_matrix
(matrix,
context
);
15
if
(!values) {
16
return
Result<void>::failure
(
17
CasErrc::Inconclusive
,
18
"Cholesky input is outside the exact rational SPD support domain"
,
19
operation);
20
}
21
const
size_t
n = values->size();
22
for
(
size_t
row = 0; row < n; ++row) {
23
for
(
size_t
col = row + 1; col < n; ++col) {
24
if
((*values)[row][col] != (*values)[col][row]) {
25
return
Result<void>::failure
(
26
CasErrc::DomainError
,
27
"Cholesky input must be symmetric"
,
28
operation);
29
}
30
}
31
}
32
for
(
size_t
order
= 1;
order
<= n; ++
order
) {
33
std::vector<Rational> leading;
34
leading.reserve(
order
*
order
);
35
for
(
size_t
row = 0; row <
order
; ++row) {
36
for
(
size_t
col = 0; col <
order
; ++col) {
37
leading.push_back((*values)[row][col]);
38
}
39
}
40
auto
determinant =
detail::rational_determinant_exact
(
41
order
, std::move(leading),
context
, operation);
42
if
(!determinant)
return
Result<void>::failure
(determinant.error());
43
if
(determinant.value() <= Rational(0)) {
44
return
Result<void>::failure
(
45
CasErrc::DomainError
,
46
"Cholesky input is not positive definite"
,
47
operation);
48
}
49
}
50
return
Result<void>::success
();
51
}
52
static
bool
cholesky_decomposition_impl
(
53
const
std::shared_ptr<SymbolicExpr>& A,
54
std::shared_ptr<SymbolicExpr>& L) {
55
auto
mat = std::dynamic_pointer_cast<const MatrixNode>(
LMCAS::detail::node
(A));
56
if
(!mat || mat->rows() != mat->cols())
return
false
;
57
size_t
n = mat->rows();
58
std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> L_grid(n, std::vector<std::shared_ptr<SymbolicExpr>>(n, SymbolicExpr::number(0)));
59
for
(
size_t
i = 0; i < n; i++) {
60
for
(
size_t
j = 0; j <= i; j++) {
61
auto
sum = SymbolicExpr::number(0);
62
for
(
size_t
k = 0; k < j; k++) sum = SymbolicExpr::add(sum, SymbolicExpr::multiply(L_grid[i][k], L_grid[j][k]));
63
auto
a_ij =
LMCAS::detail::make_expression_ptr
(mat->get(i, j));
64
auto
diff = SymbolicExpr::add(a_ij, SymbolicExpr::multiply(SymbolicExpr::number(-1), sum));
65
if
(i == j) L_grid[i][j] = SymbolicExpr::sqrt(diff);
66
else
L_grid[i][j] = SymbolicExpr::divide(diff, L_grid[j][j]);
67
}
68
}
69
L = SymbolicExpr::matrix(L_grid);
70
return
true
;
71
}
72
}
73
74
CholeskyDecompositionResult
cholesky_decomposition_checked
(
75
const
std::shared_ptr<SymbolicExpr>& A,
76
ComputationContext
&
context
)
77
{
78
const
std::string operation =
"cholesky_decomposition"
;
79
auto
matrix =
validate_decomposition_matrix
(A,
true
,
context
, operation);
80
if
(!matrix)
return
CholeskyDecompositionResult::failure
(matrix.error());
81
auto
budget =
context
.consume_steps(matrix.value()->rows() * matrix.value()->cols() * 10 + 8,
82
operation);
83
if
(!budget)
return
CholeskyDecompositionResult::failure
(budget.error());
84
auto
spd = prove_exact_spd(matrix.value(),
context
, operation);
85
if
(!spd)
return
CholeskyDecompositionResult::failure
(spd.error());
86
try
{
87
std::shared_ptr<SymbolicExpr> L;
88
if
(!cholesky_decomposition_impl(A, L)) {
89
return
CholeskyDecompositionResult::failure
(
90
CasErrc::Inconclusive
,
91
"Cholesky decomposition could not be constructed in the supported symbolic domain"
,
92
operation);
93
}
94
auto
l_check =
validate_decomposition_output
(L,
"L"
, operation);
95
if
(!l_check)
return
CholeskyDecompositionResult::failure
(l_check.error());
96
return
CholeskyDecompositionResult::success
(
CholeskyDecomposition
{L});
97
}
catch
(
const
std::bad_alloc&) {
98
return
CholeskyDecompositionResult::failure
(
99
CasErrc::ResourceLimit
,
100
"allocation failed while calculating Cholesky decomposition"
,
101
operation);
102
}
catch
(
const
std::exception& ex) {
103
return
CholeskyDecompositionResult::failure
(
CasErrc::InternalInvariant
,
104
ex.what(),
105
operation);
106
}
107
}
108
109
CholeskyDecompositionResult
cholesky_decomposition_checked
(
110
const
std::shared_ptr<SymbolicExpr>& A)
111
{
112
ComputationContext
context
;
113
return
cholesky_decomposition_checked
(A,
context
);
114
}
115
116
}
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_rational_matrix.hpp
matrix_decomposition_support.hpp
LMCAS::anonymous_namespace{matrix_decomposition_cholesky.cpp}::prove_exact_spd
Result< void > prove_exact_spd(const std::shared_ptr< const MatrixNode > &matrix, ComputationContext &context, const std::string &operation)
定义
matrix_decomposition_cholesky.cpp:10
LMCAS::anonymous_namespace{matrix_decomposition_cholesky.cpp}::cholesky_decomposition_impl
static bool cholesky_decomposition_impl(const std::shared_ptr< SymbolicExpr > &A, std::shared_ptr< SymbolicExpr > &L)
定义
matrix_decomposition_cholesky.cpp:52
LMCAS::detail::matrix_decomposition
定义
matrix_decomposition_support.hpp:9
LMCAS::detail::matrix_decomposition::validate_decomposition_matrix
Result< std::shared_ptr< const MatrixNode > > validate_decomposition_matrix(const std::shared_ptr< SymbolicExpr > &A, bool require_square, ComputationContext &context, const std::string &operation)
定义
matrix_decomposition_support.cpp:6
LMCAS::detail::matrix_decomposition::validate_decomposition_output
Result< void > validate_decomposition_output(const std::shared_ptr< SymbolicExpr > &expr, const std::string &name, const std::string &operation)
定义
matrix_decomposition_support.cpp:36
LMCAS::detail::matrix_decomposition::exact_rational_matrix
std::optional< std::vector< std::vector< Rational > > > exact_rational_matrix(const std::shared_ptr< const MatrixNode > &matrix, ComputationContext &context)
定义
matrix_decomposition_support.cpp:123
LMCAS::detail::make_expression_ptr
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
定义
base.hpp:111
LMCAS::detail::node
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
定义
base.hpp:91
LMCAS::detail::rational_determinant_exact
Result< Rational > rational_determinant_exact(std::size_t dimension, std::vector< Rational > values, ComputationContext &context, const std::string &operation)
定义
exact_rational_determinant.cpp:62
LMCAS
定义
assumption.hpp:11
LMCAS::context
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
定义
exact_factorization.hpp:65
LMCAS::order
const std::vector< FGLMPoly > const MonomialOrder & order
定义
fglm.hpp:103
LMCAS::CasErrc::Inconclusive
@ Inconclusive
定义
result.hpp:24
LMCAS::CasErrc::InternalInvariant
@ InternalInvariant
定义
result.hpp:28
LMCAS::CasErrc::ResourceLimit
@ ResourceLimit
定义
result.hpp:25
LMCAS::CasErrc::DomainError
@ DomainError
定义
result.hpp:16
LMCAS::cholesky_decomposition_checked
CholeskyDecompositionResult cholesky_decomposition_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)
定义
matrix_decomposition_cholesky.cpp:74
LMCAS::CholeskyDecompositionResult
Result< CholeskyDecomposition > CholeskyDecompositionResult
定义
matrix_decomposition.hpp:43
LMCAS::CholeskyDecomposition
定义
matrix_decomposition.hpp:26
src
matrix_decomposition_cholesky.cpp
生成于
, 为 LMCAS使用
1.18.0