LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
symbolic_algebra_adapter.cpp
浏览该文件的文档.
1#include "poly_utils.hpp"
2
3
4namespace LMCAS {
5namespace {
6
7using ResultantMatrix = std::vector<std::vector<Rational>>;
8
11 const int left_degree = left.degree();
12 const int right_degree = right.degree();
13 const int size = left_degree + right_degree;
14 ResultantMatrix matrix(size, std::vector<Rational>(size, Rational(0)));
15 for (int row = 0; row < right_degree; ++row) {
16 for (int column = 0; column <= left_degree; ++column) {
17 matrix[row][row + column] = left.coeffs[left_degree - column];
18 }
19 }
20 for (int row = 0; row < left_degree; ++row) {
21 for (int column = 0; column <= right_degree; ++column) {
22 matrix[right_degree + row][row + column] =
23 right.coeffs[right_degree - column];
24 }
25 }
26 return matrix;
27}
28
30 const Rational& previous) {
31 const int size = static_cast<int>(matrix.size());
32 for (int row = pivot + 1; row < size; ++row) {
33 for (int column = pivot + 1; column < size; ++column) {
34 matrix[row][column] =
35 (matrix[row][column] * matrix[pivot][pivot] -
36 matrix[row][pivot] * matrix[pivot][column]) / previous;
37 }
38 matrix[row][pivot] = Rational(0);
39 }
40}
41
43 Rational previous(1);
44 int sign = 1;
45 const int size = static_cast<int>(matrix.size());
46 for (int pivot = 0; pivot < size; ++pivot) {
47 if (matrix[pivot][pivot] == Rational(0)) {
48 int replacement = pivot + 1;
49 while (replacement < size &&
50 matrix[replacement][pivot] == Rational(0)) {
51 ++replacement;
52 }
53 if (replacement == size) { return Rational(0); }
54 std::swap(matrix[pivot], matrix[replacement]);
55 sign = -sign;
56 }
57 eliminate_resultant_column(matrix, pivot, previous);
58 previous = matrix[pivot][pivot];
59 }
60 auto determinant = matrix.back().back();
61 if (sign < 0) { determinant = Rational(0) - determinant; }
62 return determinant;
63}
64
65}
66
67std::shared_ptr<SymbolicExpr> SymbolicExpr::poly_resultant(
68 const std::shared_ptr<SymbolicExpr>& left,
69 const std::shared_ptr<SymbolicExpr>& right,
70 const std::string& variable) {
71 if (!left || !right || variable.empty()) { return nullptr; }
72
73 try {
74 auto left_conversion = LMCAS::symbolic_to_poly<Rational>(left, variable);
75 auto right_conversion = LMCAS::symbolic_to_poly<Rational>(right, variable);
76 if (!left_conversion || !right_conversion) return nullptr;
77 const auto& left_poly = left_conversion.value();
78 const auto& right_poly = right_conversion.value();
79 const int left_degree = left_poly.degree();
80 const int right_degree = right_poly.degree();
81 if (left_degree < 0 || right_degree < 0) { return SymbolicExpr::number(0); }
82 if (left_degree == 0 && right_degree == 0) { return SymbolicExpr::number(1); }
83
84 auto matrix = sylvester_matrix(left_poly, right_poly);
85 return SymbolicExpr::number(resultant_determinant(matrix));
86 } catch (const std::exception&) {
87 return nullptr;
88 }
89}
90
91} // namespace LMCAS
一元多项式模板类
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
int degree() const
获取多项式的次数
ResultantMatrix sylvester_matrix(const Polynomial< Rational > &left, const Polynomial< Rational > &right)
void eliminate_resultant_column(ResultantMatrix &matrix, int pivot, const Rational &previous)
PolyMatrix sylvester_matrix(const std::vector< Poly > &left, const std::vector< Poly > &right, const std::string &variable)
Result< Poly > resultant_determinant(PolyMatrix matrix, const std::string &variable, ComputationContext &context, const std::string &operation)
const std::string & variable
const ExprPtr & right
多项式转换与精确符号多项式代数。