14 const std::shared_ptr<SymbolicExpr>& A,
const std::string&
variable,
16 constexpr const char* operation =
"matrix_characteristic_polynomial";
22 "characteristic polynomial variable cannot be empty", operation);
25 const auto& matrix = *matrix_result.value();
26 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> entries(
28 std::vector<std::shared_ptr<SymbolicExpr>>(matrix.cols()));
29 auto lambda = SymbolicExpr::variable(
variable);
30 for (std::size_t row = 0; row < matrix.rows(); ++row) {
31 for (std::size_t column = 0; column < matrix.cols(); ++column) {
33 matrix.get(row, column));
34 entries[row][column] = row == column
37 SymbolicExpr::multiply(
38 lambda, SymbolicExpr::number(-1)))
43 SymbolicExpr::matrix(entries),
context);
46 std::move(determinant.value()));
47 }
catch (
const std::bad_alloc&) {
50 "allocation failed while constructing characteristic polynomial",
52 }
catch (
const std::exception& ex) {
59 const std::shared_ptr<SymbolicExpr>& A,
const std::string&
variable) {
67 (
context).limits().max_ast_nodes,
"transform");
68 constexpr const char* operation =
"matrix_eigenvalues";
73 const auto& matrix = *matrix_result.value();
74 bool triangular =
true;
75 for (std::size_t row = 0; row < matrix.rows() && triangular; ++row) {
76 for (std::size_t column = 0; column < row; ++column) {
86 std::vector<std::shared_ptr<SymbolicExpr>> values;
87 values.reserve(matrix.rows());
88 for (std::size_t index = 0; index < matrix.rows(); ++index) {
103 std::vector<std::shared_ptr<SymbolicExpr>> values;
104 std::set<std::string> seen;
106 const auto key = root->to_string();
107 if (seen.insert(key).second) values.push_back(std::move(root));
109 if (values.empty()) {
112 "eigenvalue solver produced no finite roots", operation);
115}
catch (
const CasError& error) {
117}
catch (
const std::bad_alloc&) {
119}
catch (
const std::length_error& error) {
121}
catch (
const std::exception& error) {
126 const std::shared_ptr<SymbolicExpr>& A) {
132using Eigenspaces = std::vector<std::pair<ExprPtr, std::vector<std::vector<ExprPtr>>>>;
138 (
context).limits().max_ast_nodes,
"transform");
139 constexpr const char* operation =
"matrix_eigenspaces";
140 for (
const auto& space : spaces) {
142 auto difference = SymbolicExpr::add(lambda,
143 SymbolicExpr::multiply(SymbolicExpr::number(-1), space.first));
151 "eigenvalues cannot be proved pointwise distinct", operation);
157}
catch (
const std::bad_alloc&) {
159}
catch (
const std::length_error& error) {
161}
catch (
const std::exception& error) {
168 (
context).limits().max_ast_nodes,
"transform");
169 std::vector<std::vector<std::shared_ptr<SymbolicExpr>>> shifted(
171 std::vector<std::shared_ptr<SymbolicExpr>>(matrix.
cols()));
172 for (std::size_t row = 0; row < matrix.
rows(); ++row) {
173 for (std::size_t column = 0; column < matrix.
cols(); ++column) {
175 shifted[row][column] = row == column
177 SymbolicExpr::number(-1), lambda))), transform_budget))
183 if (nullspace.value().empty()) {
185 "eigenvalue has no proved nonzero nullspace basis",
"matrix_eigenspaces");
190}
catch (
const std::bad_alloc&) {
192}
catch (
const std::length_error& error) {
194}
catch (
const std::exception& error) {
202 (
context).limits().max_ast_nodes,
"transform");
204 constexpr const char*
operation =
"matrix_eigenspaces";
206 if (!matrix_result) {
return SpacesResult::failure(matrix_result.error()); }
208 if (!eigenvalues) {
return SpacesResult::failure(eigenvalues.error()); }
209 const auto& matrix = *matrix_result.value();
211 AssumptionContext assumptions;
214 for (
const auto& eigenvalue : eigenvalues.value()) {
216 auto duplicate = eigenvalue_already_collected(lambda, spaces,
context,
facts);
217 if (!duplicate) {
return SpacesResult::failure(duplicate.error()); }
218 if (duplicate.value()) {
continue; }
219 auto nullspace = eigenvalue_nullspace(matrix, lambda,
context);
220 if (!nullspace) {
return SpacesResult::failure(nullspace.error()); }
221 spaces.emplace_back(std::move(lambda), std::move(nullspace.value()));
223 return SpacesResult::success(std::move(spaces));
224 }
catch (
const std::bad_alloc&) {
226 "allocation failed while computing eigenspaces",
operation);
232}
catch (
const std::bad_alloc&) {
233 return Result<std::vector<std::pair<ExprPtr, std::vector<std::vector<ExprPtr>>>>>::failure(
CasErrc::ResourceLimit,
"allocation failed",
"matrix_eigenspaces");
234}
catch (
const std::length_error& error) {
236}
catch (
const std::exception& error) {
245 std::vector<std::vector<ExprPtr>> vectors;
246 for (
auto& space : spaces.value())
247 for (
auto& vector : space.second) vectors.push_back(std::move(vector));
249 }
catch (
const std::bad_alloc&) {
251 "allocation failed while collecting eigenvectors",
"matrix_eigenvectors");
256 const std::shared_ptr<SymbolicExpr>& A) {
AssumptionContext class with scoped push/pop management.
size_t cols() const noexcept
size_t rows() const noexcept
std::shared_ptr< const SymbolicNode > get(size_t r, size_t c) const
获取指定位置的矩阵元素。
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(std::shared_ptr< SymbolicExpr > value)
Result< bool > eigenvalue_already_collected(const ExprPtr &lambda, const Eigenspaces &spaces, ComputationContext &context, const detail::AssumptionFacts &facts)
std::vector< std::pair< ExprPtr, std::vector< std::vector< ExprPtr > > > > Eigenspaces
MatrixEigenvectorResult eigenvalue_nullspace(const MatrixNode &matrix, const ExprPtr &lambda, ComputationContext &context)
Result< std::shared_ptr< const MatrixNode > > require_square_matrix(const std::shared_ptr< SymbolicExpr > &expr, ComputationContext &context, const std::string &operation)
Result< ZeroProof > classify_exact_zero(const ExprPtr &expression, ComputationContext &context, const std::string &operation)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
Result< Tribool > query_nonzero_value(const Node &node, const FactsQuery &facts, Domain domain, ComputationContext &context)
RewriteBudget const FactsQuery & facts
ComputationContext const std::string & operation
SymbolicNodePtr normalize_node(const SymbolicNodePtr &node, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::size_t std::size_t ComputationContext & context
Result< std::vector< std::pair< ExprPtr, std::vector< std::vector< ExprPtr > > > > > matrix_eigenspaces_checked(const ExprPtr &matrix, ComputationContext &context)
MatrixEigenvalueResult matrix_eigenvalues_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)
const std::string & variable
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExpressionResult matrix_characteristic_polynomial_checked(const std::shared_ptr< SymbolicExpr > &A, const std::string &variable, ComputationContext &context)
@ Complex
Complex numbers (default, least specific)
ExpressionResult matrix_determinant_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)
@ True
Property definitely holds
Result< std::vector< std::shared_ptr< SymbolicExpr > > > MatrixEigenvalueResult
Result< std::shared_ptr< SymbolicExpr > > ExpressionResult
Result of an operation that produces a symbolic expression.
Result< std::vector< std::vector< std::shared_ptr< SymbolicExpr > > > > MatrixEigenvectorResult
LMCAS::FiniteSolveResult solve_finite_checked(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, const SolveOptions &opts)
std::shared_ptr< SymbolicExpr > ExprPtr
MatrixEigenvectorResult matrix_eigenvectors_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
const std::string const ExprPtr & value
MatrixNullspaceResult matrix_nullspace_checked(const std::shared_ptr< SymbolicExpr > &A, ComputationContext &context)
方程求解策略调度器 solve_dispatch 及相关选项结构体.