LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
rational_polynomial.cpp
浏览该文件的文档.
1
#include "
rational_polynomial.hpp
"
2
#include <algorithm>
3
#include <optional>
4
5
namespace
LMCAS
{
6
7
static
std::vector<BigInt>
positive_divisors
(
const
BigInt& n) {
8
std::vector<BigInt> divs;
9
if
(n.is_zero()) {
10
11
return
divs;
12
}
13
BigInt abs_n = n.abs();
14
15
BigInt i(1);
16
17
while
(i * i <= abs_n) {
18
BigInt rem = abs_n % i;
19
if
(rem.is_zero()) {
20
divs.push_back(i);
21
BigInt counterpart = abs_n / i;
22
if
(counterpart != i) {
23
divs.push_back(counterpart);
24
}
25
}
26
i = i + BigInt(1);
27
}
28
29
std::sort(divs.begin(), divs.end());
30
return
divs;
31
}
32
33
static
std::optional<Rational>
rational_root_candidate
(
34
const
Polynomial<Rational>
& current) {
35
BigInt denominator_lcm(1);
36
for
(
const
auto
& coefficient : current.
coeffs
) {
37
denominator_lcm = BigInt::lcm(
38
denominator_lcm, coefficient.get_denominator());
39
}
40
const
Rational scale(denominator_lcm);
41
const
auto
numerators =
positive_divisors
(
42
(current.
coeffs
[0] * scale).get_numerator());
43
const
auto
denominators =
positive_divisors
(
44
(current.
lead_coeff
() * scale).get_numerator());
45
for
(
const
auto
& numerator : numerators) {
46
for
(
const
auto
&
denominator
: denominators) {
47
Rational positive(numerator,
denominator
);
48
if
(current.
eval
(positive) == Rational(0))
return
positive;
49
Rational negative(-numerator,
denominator
);
50
if
(current.
eval
(negative) == Rational(0))
return
negative;
51
}
52
}
53
return
std::nullopt;
54
}
55
56
static
void
deflate_rational_root
(
Polynomial<Rational>
& current,
57
const
Rational& root,
58
std::vector<Rational>&
roots
) {
59
Polynomial<Rational>
linear({-root, Rational(1)}, current.
variable_name
);
60
while
(current.
degree
() >= 1) {
61
auto
[quotient, remainder] = current.
div_mod
(linear);
62
if
(!remainder.is_zero())
break
;
63
roots
.push_back(root);
64
current = std::move(quotient);
65
if
(current.
degree
() < 1 || current.
eval
(root) != Rational(0))
break
;
66
}
67
}
68
69
std::vector<Rational>
find_rational_roots
(
const
Polynomial<Rational>
& poly) {
70
std::vector<Rational>
roots
;
71
if
(poly.
is_zero
() || poly.
degree
() < 1)
return
roots
;
72
Polynomial<Rational>
current = poly.
make_monic
();
73
while
(current.
degree
() >= 1) {
74
if
(current.
coeffs
[0] == Rational(0)) {
75
roots
.push_back(Rational(0));
76
std::vector<Rational> coefficients(
77
current.
coeffs
.begin() + 1, current.
coeffs
.end());
78
current =
Polynomial<Rational>
(coefficients, current.
variable_name
);
79
continue
;
80
}
81
if
(current.
degree
() == 1) {
82
roots
.push_back(-current.
coeffs
[0] / current.
lead_coeff
());
83
break
;
84
}
85
auto
candidate =
rational_root_candidate
(current);
86
if
(!candidate)
break
;
87
deflate_rational_root
(current, *candidate,
roots
);
88
}
89
return
roots
;
90
}
91
92
}
LMCAS::Polynomial
一元多项式模板类
定义
polynomial.hpp:52
LMCAS::Polynomial::eval
CoeffType eval(const CoeffType &val) const
对多项式求值(Horner 法)
定义
polynomial.hpp:294
LMCAS::Polynomial::div_mod
std::pair< Polynomial, Polynomial > div_mod(const Polynomial &other) const
多项式带余除法
定义
polynomial.hpp:207
LMCAS::Polynomial::variable_name
std::string variable_name
变量名
定义
polynomial.hpp:56
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::lead_coeff
CoeffType lead_coeff() const
获取首项系数
定义
polynomial.hpp:109
LMCAS::Polynomial::degree
int degree() const
获取多项式的次数
定义
polynomial.hpp:100
LMCAS::Polynomial::make_monic
Polynomial make_monic() const
首一化(使首项系数为 1)
定义
polynomial.hpp:324
LMCAS
定义
assumption.hpp:11
LMCAS::deflate_rational_root
static void deflate_rational_root(Polynomial< Rational > ¤t, const Rational &root, std::vector< Rational > &roots)
定义
rational_polynomial.cpp:56
LMCAS::rational_root_candidate
static std::optional< Rational > rational_root_candidate(const Polynomial< Rational > ¤t)
定义
rational_polynomial.cpp:33
LMCAS::positive_divisors
static std::vector< BigInt > positive_divisors(const BigInt &n)
定义
rational_polynomial.cpp:7
LMCAS::find_rational_roots
std::vector< Rational > find_rational_roots(const Polynomial< Rational > &poly)
定义
rational_polynomial.cpp:69
LMCAS::roots
ExprSetResult roots(const ExprPtr &expression, const std::string &variable, ComputationContext &context, const SolveOptions &options)
定义
expr_solving.cpp:80
LMCAS::denominator
const ExprPtr & denominator
定义
expr.hpp:200
rational_polynomial.hpp
src
rational_polynomial.cpp
生成于
, 为 LMCAS使用
1.18.0