LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
fglm_polynomial.cpp
浏览该文件的文档.
1#include "fglm.hpp"
2#include <algorithm>
3#include <stdexcept>
4
5namespace LMCAS {
6
7namespace {
8
10 const Monomial& left, const Monomial& right, std::size_t num_vars) {
11 Monomial result(num_vars, 0);
12 for (std::size_t i = 0; i < num_vars; ++i) {
13 const int left_value = i < left.size() ? left[i] : 0;
14 const int right_value = i < right.size() ? right[i] : 0;
15 result[i] = left_value - right_value;
16 }
17 return result;
18}
19
21 const Monomial& left, const Monomial& right, std::size_t num_vars) {
22 Monomial result(num_vars, 0);
23 for (std::size_t i = 0; i < num_vars; ++i) {
24 const int left_value = i < left.size() ? left[i] : 0;
25 const int right_value = i < right.size() ? right[i] : 0;
26 result[i] = left_value + right_value;
27 }
28 return result;
29}
30
32 FGLMPoly& polynomial, const FGLMPoly& divisor,
33 const Monomial& divisor_leading, const Monomial& leading,
34 const MonomialOrder& order) {
35 const Monomial quotient = subtract_monomials(
36 leading, divisor_leading, polynomial.num_vars);
37 const Rational coefficient =
38 polynomial.lead_coeff() / divisor.lead_coeff();
39 for (const auto& [monomial, value] : divisor.terms) {
40 polynomial.add_term(
41 add_monomials(quotient, monomial, polynomial.num_vars),
42 -(coefficient * value));
43 }
44 polynomial.sort_terms(order);
45 polynomial.normalize();
46}
47
49 FGLMPoly& polynomial, const std::vector<FGLMPoly>& basis,
50 const Monomial& leading, const MonomialOrder& order) {
51 for (const auto& divisor : basis) {
52 if (divisor.is_zero()) {
53 continue;
54 }
55 const Monomial divisor_leading = divisor.lead_monomial();
56 if (!divides_monomial(divisor_leading, leading)) {
57 continue;
58 }
60 polynomial, divisor, divisor_leading, leading, order);
61 return true;
62 }
63 return false;
64}
65
66}
67
68
69 void FGLMPoly::sort_terms(const MonomialOrder& order) {
70 std::sort(terms.begin(), terms.end(),
71 [&order](const std::pair<Monomial, Rational>& a,
72 const std::pair<Monomial, Rational>& b) {
73 return order(a.first, b.first);
74 });
75 }
76
77 void FGLMPoly::normalize() {
78
79 std::vector<std::pair<Monomial, Rational>> cleaned;
80 for (auto& [m, c] : terms) {
81 if (c.is_zero()) continue;
82 if (!cleaned.empty() && cleaned.back().first == m) {
83 cleaned.back().second = cleaned.back().second + c;
84 if (cleaned.back().second.is_zero()) {
85 cleaned.pop_back();
86 }
87 } else {
88 cleaned.emplace_back(m, c);
89 }
90 }
91 terms = std::move(cleaned);
92 }
93
94 FGLMPoly FGLMPoly::reduce(const std::vector<FGLMPoly>& basis,
95 const MonomialOrder& order) const {
96 FGLMPoly remainder(num_vars);
97 FGLMPoly polynomial = *this;
98 polynomial.sort_terms(order);
99 polynomial.normalize();
100
101 while (!polynomial.is_zero()) {
102 const Monomial previous_leading = polynomial.lead_monomial();
104 polynomial, basis, previous_leading, order)) {
105 remainder.add_term(
106 previous_leading, polynomial.lead_coeff());
107 polynomial.terms.erase(polynomial.terms.begin());
108 polynomial.normalize();
109 }
110 if (!polynomial.is_zero() &&
111 !order(previous_leading, polynomial.lead_monomial())) {
112 throw std::runtime_error(
113 "FGLM polynomial reduction did not decrease the leading monomial");
114 }
115 }
116 remainder.sort_terms(order);
117 remainder.normalize();
118 return remainder;
119 }
120
121 FGLMPoly FGLMPoly::from_monomial(const Monomial& m, size_t num_vars) {
122 FGLMPoly p(num_vars);
123 p.add_term(m, Rational(1));
124 return p;
125 }
126
127FGLMPoly normal_form(const FGLMPoly& f,
128 const std::vector<FGLMPoly>& basis,
129 const MonomialOrder& order) {
130 return f.reduce(basis, order);
131}
132
133}
单项式序比较器,支持 Lex、GrevLex、DegLex、DegRevLex
FGLM 算法:零维理想 Gröbner 基在不同单项式序之间的转换.
bool reduce_leading_term(FGLMPoly &polynomial, const std::vector< FGLMPoly > &basis, const Monomial &leading, const MonomialOrder &order)
Monomial add_monomials(const Monomial &left, const Monomial &right, std::size_t num_vars)
void subtract_leading_multiple(FGLMPoly &polynomial, const FGLMPoly &divisor, const Monomial &divisor_leading, const Monomial &leading, const MonomialOrder &order)
Monomial subtract_monomials(const Monomial &left, const Monomial &right, std::size_t num_vars)
std::vector< int > Monomial
单项式类型,以整数向量表示各变量的指数
const std::vector< FGLMPoly > const MonomialOrder & order
@ Rational
Rational numbers
const VectorField const VectorField & c
const MultiPoly & b
__attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) VectorCalculusExprResult curve_integral_scalar_checked(const std __attribute__((visibility("default"))) std const VectorField const std::string const std::shared_ptr< SymbolicExpr > & a
bool divides_monomial(const Monomial &divisor, const Monomial &target)
判断 divisor 是否整除 target
const ExprPtr & right
const std::vector< FGLMPoly > & basis
const std::string const ExprPtr & value
FGLMPoly normal_form(const FGLMPoly &f, const std::vector< FGLMPoly > &basis, const MonomialOrder &order)