LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
polynomial_division.hpp
浏览该文件的文档.
1#ifndef LMCAS_POLYNOMIAL_DIVISION_HPP
2#define LMCAS_POLYNOMIAL_DIVISION_HPP
3
4#include "polynomial.hpp"
5
6namespace LMCAS {
7
8template <typename CoeffType>
9inline CoeffType Polynomial<CoeffType>::content() const {
10 if (is_zero()) return CoeffType(0);
11 CoeffType g = coeffs[0];
12
13 if constexpr (std::is_same_v<CoeffType, Rational>) {
14 return CoeffType(1);
15 } else {
16
17 for (size_t i = 1; i < coeffs.size(); ++i) {
18 g = gcd_coeff(g, coeffs[i]);
19 if (g == CoeffType(1)) break;
20 }
21 return g;
22 }
23}
24
25template <typename CoeffType>
27 if (is_zero()) return *this;
28 CoeffType c = content();
29 if (c == CoeffType(0)) return *this;
30
31 Polynomial res = *this;
32 if (c != CoeffType(1)) {
33 for (auto& val : res.coeffs) {
34 val = val / c;
35 }
36 }
37
38 if (res.lead_coeff() < CoeffType(0)) {
39 for (auto& val : res.coeffs) {
40 val = CoeffType(0) - val;
41 }
42 }
43 return res;
44}
45
46template <typename CoeffType>
47inline std::pair<Polynomial<CoeffType>, Polynomial<CoeffType>>
49 if (other.is_zero()) throw std::runtime_error("Division by zero polynomial");
50 require_compatible_variables(other, "Polynomial::pseudo_div_mod");
51 if (is_zero()) {
52 return {Polynomial(other.variable_name), Polynomial(other.variable_name)};
53 }
54
55 int deg_rem = degree();
56 int deg_div = other.degree();
57
58 if (deg_rem < deg_div) {
59 return {Polynomial(variable_name), *this};
60 }
61
62 Polynomial remainder = *this;
63 Polynomial quotient(variable_name);
64 CoeffType lc_div = other.lead_coeff();
65
66 int delta = deg_rem - deg_div;
67 quotient.coeffs.resize(delta + 1, CoeffType(0));
68
69 while (deg_rem >= deg_div && !remainder.is_zero()) {
70 int current_diff = deg_rem - deg_div;
71 CoeffType lc_rem = remainder.lead_coeff();
72
73 for (auto& c : quotient.coeffs) c = c * lc_div;
74
75 quotient.coeffs[current_diff] = quotient.coeffs[current_diff] + lc_rem;
76
78 term.coeffs.resize(current_diff + 1, CoeffType(0));
79 term.coeffs[current_diff] = lc_rem;
80
81 for(auto& c : remainder.coeffs) c = c * lc_div;
82
83 for (size_t i = 0; i < other.coeffs.size(); ++i) {
84 size_t target_idx = i + current_diff;
85
86 if (target_idx < remainder.coeffs.size()) {
87 remainder.coeffs[target_idx] = remainder.coeffs[target_idx] - other.coeffs[i] * lc_rem;
88 }
89
90 }
91
92 remainder.trim();
93 deg_rem = remainder.degree();
94 }
95
96 return {quotient, remainder};
97}
98
99template <typename CoeffType>
102
103 return pseudo_div_mod(other).second;
104}
105
106template <typename CoeffType>
109 a.require_compatible_variables(b, "Polynomial::gcd");
110 if (b.is_zero()) return a;
111 if (a.is_zero()) return b;
112
113 if constexpr (std::is_same_v<CoeffType, Rational>) {
114
115 while (!b.is_zero()) {
116 auto [q, r] = a.div_mod(b);
117 a = b;
118 b = r;
119 }
120
121 return a.make_monic();
122 } else {
123
124 CoeffType cA = a.content();
125 CoeffType cB = b.content();
126 CoeffType c = gcd_coeff_impl(cA, cB);
127
128 a = a.primitive_part();
129 b = b.primitive_part();
130
131 while (!b.is_zero()) {
132
133 Polynomial r = a.pseudo_div_mod_rem(b);
134
135 if (r.is_zero()) {
136 a = b;
137 b = r;
138 } else {
139
140 a = b;
141 b = r.primitive_part();
142 }
143 }
144
145 if (c == CoeffType(1)) return a;
146
147 for (auto& val : a.coeffs) val = val * c;
148 return a;
149 }
150}
151
152template <typename CoeffType>
154
155 if (degree() <= 0) return *this;
156
157 Polynomial deriv = differentiate();
158 Polynomial g = gcd(*this, deriv);
159
160 auto [q, r] = div_mod(g);
161
162 if constexpr (std::is_same_v<CoeffType, Rational>) {
163 return q.make_monic();
164 }
165 return q;
166}
167
168} // namespace LMCAS
169
170#endif
一元多项式模板类
static Polynomial gcd(Polynomial a, Polynomial b)
计算两个多项式的最大公因式
Polynomial pseudo_div_mod_rem(const Polynomial &other) const
伪除法取余数
Polynomial differentiate() const
求导
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
void require_compatible_variables(const Polynomial &other, const char *operation) const
Polynomial(const std::string &var="x")
构造零多项式
std::string variable_name
变量名
static CoeffType gcd_coeff(const CoeffType &a, const CoeffType &b)
计算两个系数的 GCD(静态方法)
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
Polynomial primitive_part() const
计算多项式的本原部分(除以容度)
Polynomial square_free_part() const
计算无平方因子部分
std::pair< Polynomial, Polynomial > pseudo_div_mod(const Polynomial &other) const
通过系数缩放执行伪除法,运算保持在原系数环
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
CoeffType content() const
计算多项式的容度(所有系数的 GCD)
void trim()
去除高次零系数
__attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_exp_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexSymbolicResult complex_trig_form_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_nth_root_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std __attribute__((visibility("default"))) ComplexRootsResult solve_complex_quadratic_checked(std std::shared_ptr< SymbolicExpr > r
const VectorField const VectorField & c
const MultiPoly & b
T gcd_coeff_impl(const T &a, const T &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
一元多项式模板类 Polynomial<T>,支持四则运算,GCD,求导,求值.