LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
polynomial_division.hpp
浏览该文件的文档.
1
#ifndef LMCAS_POLYNOMIAL_DIVISION_HPP
2
#define LMCAS_POLYNOMIAL_DIVISION_HPP
3
4
#include "
polynomial.hpp
"
5
6
namespace
LMCAS
{
7
8
template
<
typename
CoeffType>
9
inline
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
25
template
<
typename
CoeffType>
26
inline
Polynomial<CoeffType>
Polynomial<CoeffType>::primitive_part
()
const
{
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
46
template
<
typename
CoeffType>
47
inline
std::pair<Polynomial<CoeffType>,
Polynomial<CoeffType>
>
48
Polynomial<CoeffType>::pseudo_div_mod
(
const
Polynomial<CoeffType>
& other)
const
{
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
77
Polynomial
term(
variable_name
);
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
99
template
<
typename
CoeffType>
100
inline
Polynomial<CoeffType>
101
Polynomial<CoeffType>::pseudo_div_mod_rem
(
const
Polynomial<CoeffType>
& other)
const
{
102
103
return
pseudo_div_mod
(other).second;
104
}
105
106
template
<
typename
CoeffType>
107
inline
Polynomial<CoeffType>
Polynomial<CoeffType>::gcd
(
108
Polynomial<CoeffType>
a
,
Polynomial<CoeffType>
b
) {
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
152
template
<
typename
CoeffType>
153
inline
Polynomial<CoeffType>
Polynomial<CoeffType>::square_free_part
()
const
{
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
LMCAS::Polynomial
一元多项式模板类
定义
polynomial.hpp:52
LMCAS::Polynomial::gcd
static Polynomial gcd(Polynomial a, Polynomial b)
计算两个多项式的最大公因式
定义
polynomial_division.hpp:107
LMCAS::Polynomial::pseudo_div_mod_rem
Polynomial pseudo_div_mod_rem(const Polynomial &other) const
伪除法取余数
定义
polynomial_division.hpp:101
LMCAS::Polynomial::differentiate
Polynomial differentiate() const
求导
定义
polynomial.hpp:307
LMCAS::Polynomial::div_mod
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
定义
polynomial.hpp:207
LMCAS::Polynomial::require_compatible_variables
void require_compatible_variables(const Polynomial &other, const char *operation) const
定义
polynomial.hpp:382
LMCAS::Polynomial::Polynomial
Polynomial(const std::string &var="x")
构造零多项式
定义
polynomial.hpp:62
LMCAS::Polynomial::variable_name
std::string variable_name
变量名
定义
polynomial.hpp:56
LMCAS::Polynomial::gcd_coeff
static CoeffType gcd_coeff(const CoeffType &a, const CoeffType &b)
计算两个系数的 GCD(静态方法)
定义
polynomial.hpp:253
LMCAS::Polynomial::is_zero
bool is_zero() const
判断是否为零多项式
定义
polynomial.hpp:92
LMCAS::Polynomial::coeffs
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
定义
polynomial.hpp:55
LMCAS::Polynomial::primitive_part
Polynomial primitive_part() const
计算多项式的本原部分(除以容度)
定义
polynomial_division.hpp:26
LMCAS::Polynomial::square_free_part
Polynomial square_free_part() const
计算无平方因子部分
定义
polynomial_division.hpp:153
LMCAS::Polynomial::pseudo_div_mod
std::pair< Polynomial, Polynomial > pseudo_div_mod(const Polynomial &other) const
通过系数缩放执行伪除法,运算保持在原系数环
定义
polynomial_division.hpp:48
LMCAS::Polynomial::lead_coeff
CoeffType lead_coeff() const
获取首项系数
定义
polynomial.hpp:109
LMCAS::Polynomial::degree
int degree() const
获取多项式的次数
定义
polynomial.hpp:100
LMCAS::Polynomial::content
CoeffType content() const
计算多项式的容度(所有系数的 GCD)
定义
polynomial_division.hpp:9
LMCAS::Polynomial::trim
void trim()
去除高次零系数
定义
polynomial.hpp:85
LMCAS
定义
assumption.hpp:11
LMCAS::r
__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
定义
symbolic_complex.hpp:209
LMCAS::c
const VectorField const VectorField & c
定义
vector_calculus_vectors.hpp:60
LMCAS::b
const MultiPoly & b
定义
multivariate_factor.hpp:92
LMCAS::gcd_coeff_impl
T gcd_coeff_impl(const T &a, const T &b)
计算两个系数的最大公约数(泛型实现)
定义
polynomial.hpp:26
LMCAS::a
__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
定义
vector_calculus_curves.hpp:50
polynomial.hpp
一元多项式模板类 Polynomial<T>,支持四则运算,GCD,求导,求值.
include
polynomial_division.hpp
生成于
, 为 LMCAS使用
1.18.0