LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
univariate_factor_bridge.cpp
浏览该文件的文档.
1
#include "
internal/multivariate_factor_support.hpp
"
2
#include "
exact_factorization.hpp
"
3
#include <exception>
4
#include <iterator>
5
#include <new>
6
#include <utility>
7
8
namespace
LMCAS
{
9
Polynomial<BigInt>
factor_integer_polynomial
(
const
Polynomial<Rational>
& poly) {
10
BigInt denominator_lcm(1);
11
for
(
const
auto
& coefficient : poly.
coeffs
) {
12
denominator_lcm = BigInt::lcm(
13
denominator_lcm, coefficient.get_denominator());
14
}
15
std::vector<BigInt> coefficients;
16
coefficients.reserve(poly.
coeffs
.size());
17
for
(
const
auto
& coefficient : poly.
coeffs
) {
18
coefficients.push_back(coefficient.get_numerator() *
19
(denominator_lcm / coefficient.get_denominator()));
20
}
21
return
Polynomial<BigInt>
(coefficients, poly.
variable_name
);
22
}
23
namespace
{
24
25
constexpr
const
char
*
bridge_operation
=
"factor_univariate"
;
26
27
UnivariateFactorResult
bridge_inconclusive
(
28
const
Polynomial<Rational>
& poly,
const
char
* reason) {
29
return
UnivariateFactorResult::success
(
30
MathResult
<std::vector<
Polynomial<Rational>
>>{
31
{poly.
make_monic
()},
Completeness::Inconclusive
, reason});
32
}
33
34
Result<BerlekampResult>
bridge_reduction
(
35
const
Polynomial<Rational>
& poly,
ComputationContext
&
context
) {
36
static
const
int64_t primes[] = {3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
37
for
(int64_t
prime
: primes) {
38
auto
step =
context
.consume_steps(1,
bridge_operation
);
39
if
(!step)
return
Result<BerlekampResult>::failure
(step.error());
40
auto
reduction =
berlekamp_factor
(poly,
prime
);
41
if
(reduction.prime > 0 && !reduction.factors.empty() &&
42
(poly.
degree
() == 1 ||
43
static_cast<
int
>
(reduction.factors.size()) == reduction.null_space_dim)) {
44
return
Result<BerlekampResult>::success
(std::move(reduction));
45
}
46
}
47
return
Result<BerlekampResult>::success
(
BerlekampResult
{});
48
}
49
50
51
Result<int>
bridge_lift_bound
(
const
Polynomial<BigInt>
& poly, int64_t
prime
,
52
BigInt& modulus,
ComputationContext
&
context
) {
53
BigInt coefficient_sum(0);
54
for
(
const
auto
& coefficient : poly.
coeffs
) {
55
coefficient_sum = coefficient_sum + coefficient.abs();
56
}
57
BigInt
target
= coefficient_sum * BigInt(2);
58
for
(
int
i = 0; i < poly.
degree
(); ++i)
target
=
target
* BigInt(2);
59
int
bound = 1;
60
modulus = BigInt(
static_cast<
std::int64_t
>
(
prime
));
61
while
(modulus <=
target
&& bound < 100) {
62
auto
step =
context
.consume_steps(1,
bridge_operation
);
63
if
(!step)
return
Result<int>::failure
(step.error());
64
modulus = modulus * BigInt(
static_cast<
std::int64_t
>
(
prime
));
65
++bound;
66
}
67
if
(modulus <=
target
) {
68
return
Result<int>::failure
(
CasErrc::Inconclusive
,
69
"提升次数上限不足以保证重构"
,
bridge_operation
);
70
}
71
return
Result<int>::success
(bound);
72
}
73
74
bool
bridge_inconclusive_error
(
const
CasError
& error) {
75
return
error.
code
==
CasErrc::InvalidArgument
|| error.
code
==
CasErrc::Inconclusive
;
76
}
77
78
UnivariateFactorResult
bridge_lift_and_combine
(
79
const
Polynomial<Rational>
& original,
const
Polynomial<Rational>
& work,
80
BerlekampResult
& reduction,
ComputationContext
&
context
,
bool
& whole_input) {
81
auto
integer_poly =
factor_integer_polynomial
(work);
82
BigInt modulus;
83
auto
bound =
bridge_lift_bound
(integer_poly, reduction.
prime
, modulus,
context
);
84
if
(!bound) {
85
if
(bound.error().code ==
CasErrc::Inconclusive
) {
86
whole_input =
true
;
87
return
bridge_inconclusive
(original, bound.error().message.c_str());
88
}
89
return
UnivariateFactorResult::failure
(bound.error());
90
}
91
const
ModInt
unit
(
92
(integer_poly.coeffs.back() % BigInt(reduction.
prime
)).to_int(),
93
reduction.
prime
);
94
for
(
auto
& coefficient : reduction.
factors
.front().coeffs) {
95
coefficient = coefficient *
unit
;
96
}
97
auto
lifted =
hensel_lift_checked
(
98
integer_poly, reduction.
factors
, reduction.
prime
, bound.value());
99
if
(!lifted) {
100
if
(
bridge_inconclusive_error
(lifted.error())) {
101
whole_input =
true
;
102
return
bridge_inconclusive
(original,
"当前模素数的提升前置条件不成立"
);
103
}
104
return
UnivariateFactorResult::failure
(lifted.error());
105
}
106
auto
combined =
zassenhaus_combine_checked
(work, lifted.value(), modulus,
context
);
107
if
(!combined &&
bridge_inconclusive_error
(combined.error())) {
108
whole_input =
true
;
109
return
bridge_inconclusive
(original,
"提升因子无法完成精确有理重构"
);
110
}
111
return
combined;
112
}
113
114
Result<void>
bridge_append_repeated
(
115
MathResult
<std::vector<
Polynomial<Rational>
>>& factors,
116
const
TfSquareFreeResult
& square_free,
ComputationContext
&
context
) {
117
if
(!square_free.
had_repeated_factors
|| square_free.
repeated_factor
.
degree
() < 1) {
118
return
Result<void>::success
();
119
}
120
auto
repeated =
factor_univariate_bridge_checked
(square_free.
repeated_factor
,
context
);
121
if
(!repeated)
return
Result<void>::failure
(repeated.error());
122
if
(repeated.value().completeness ==
Completeness::Inconclusive
) {
123
factors.completeness =
Completeness::Inconclusive
;
124
if
(factors.reason.empty()) factors.reason = repeated.value().reason;
125
}
126
auto
& values = repeated.value().value;
127
factors.value.insert(factors.value.end(), std::make_move_iterator(values.begin()),
128
std::make_move_iterator(values.end()));
129
return
Result<void>::success
();
130
}
131
132
UnivariateFactorResult
bridge_factor
(
const
Polynomial<Rational>
& poly,
133
ComputationContext
&
context
) {
134
auto
square_free =
tf_square_free
(poly);
135
auto
work = square_free.square_free.make_monic();
136
auto
reduction =
bridge_reduction
(work,
context
);
137
if
(!reduction)
return
UnivariateFactorResult::failure
(reduction.error());
138
if
(reduction.value().factors.empty()) {
139
return
bridge_inconclusive
(poly,
"未找到保持次数且无平方的有效模素数"
);
140
}
141
MathResult<std::vector<Polynomial<Rational>
>> factors{
142
{},
Completeness::Complete
, {}};
143
if
(reduction.value().factors.size() <= 1) {
144
factors.
value
.push_back(work.make_monic());
145
}
else
{
146
bool
whole_input =
false
;
147
auto
combined =
bridge_lift_and_combine
(
148
poly, work, reduction.value(),
context
, whole_input);
149
if
(!combined)
return
combined;
150
if
(whole_input)
return
combined;
151
factors = std::move(combined.value());
152
}
153
auto
appended =
bridge_append_repeated
(factors, square_free,
context
);
154
if
(!appended)
return
UnivariateFactorResult::failure
(appended.error());
155
Polynomial<Rational>
product({Rational(1)}, poly.
variable_name
);
156
for
(
const
auto
& factor : factors.
value
) product = product * factor;
157
if
(!(product == poly.
make_monic
())) {
158
return
UnivariateFactorResult::failure
(
CasErrc::InternalInvariant
,
159
"一元因子未能精确重构输入多项式"
,
bridge_operation
);
160
}
161
return
UnivariateFactorResult::success
(std::move(factors));
162
}
163
164
}
165
166
UnivariateFactorResult
factor_univariate_bridge_checked
(
167
const
Polynomial<Rational>
& poly,
ComputationContext
&
context
) {
168
auto
step =
context
.consume_steps(1, bridge_operation);
169
if
(!step)
return
UnivariateFactorResult::failure
(step.error());
170
if
(poly.
is_zero
() || poly.
degree
() <= 0) {
171
return
UnivariateFactorResult::success
(
172
MathResult
<std::vector<
Polynomial<Rational>
>>{
173
poly.
is_zero
() ? std::vector<Polynomial<Rational>>{}
174
: std::vector<Polynomial<Rational>>{poly},
175
Completeness::Complete
, {}});
176
}
177
if
(poly.
degree
() == 1) {
178
return
UnivariateFactorResult::success
(
179
MathResult
<std::vector<
Polynomial<Rational>
>>{
180
{poly.
make_monic
()},
Completeness::Complete
, {}});
181
}
182
try
{
183
return
bridge_factor(poly,
context
);
184
}
catch
(
const
std::bad_alloc&) {
185
return
UnivariateFactorResult::failure
(
186
CasErrc::ResourceLimit
,
"一元分解分配失败"
, bridge_operation);
187
}
catch
(
const
std::exception& error) {
188
return
UnivariateFactorResult::failure
(
189
CasErrc::InternalInvariant
, error.what(), bridge_operation);
190
}
191
}
192
193
}
LMCAS::ComputationContext
定义
computation_context.hpp:99
LMCAS::ModInt
模整数类,封装模 p 下的算术运算
定义
modular_arithmetic.hpp:126
LMCAS::Polynomial
一元多项式模板类
定义
polynomial.hpp:52
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::degree
int degree() const
获取多项式的次数
定义
polynomial.hpp:100
LMCAS::Polynomial::make_monic
Polynomial make_monic() const
首一化(使首项系数为 1)
定义
polynomial.hpp:324
LMCAS::Result
定义
result.hpp:39
LMCAS::Result::failure
static Result failure(CasErrc code, std::string message, std::string operation={})
定义
result.hpp:52
LMCAS::Result< MathResult< std::vector< Polynomial< Rational > > > >::success
static Result success(MathResult< std::vector< Polynomial< Rational > > > value)
定义
result.hpp:48
exact_factorization.hpp
multivariate_factor_support.hpp
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_lift_bound
Result< int > bridge_lift_bound(const Polynomial< BigInt > &poly, int64_t prime, BigInt &modulus, ComputationContext &context)
定义
univariate_factor_bridge.cpp:51
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_operation
constexpr const char * bridge_operation
定义
univariate_factor_bridge.cpp:25
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_reduction
Result< BerlekampResult > bridge_reduction(const Polynomial< Rational > &poly, ComputationContext &context)
定义
univariate_factor_bridge.cpp:34
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_inconclusive
UnivariateFactorResult bridge_inconclusive(const Polynomial< Rational > &poly, const char *reason)
定义
univariate_factor_bridge.cpp:27
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_factor
UnivariateFactorResult bridge_factor(const Polynomial< Rational > &poly, ComputationContext &context)
定义
univariate_factor_bridge.cpp:132
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_append_repeated
Result< void > bridge_append_repeated(MathResult< std::vector< Polynomial< Rational > > > &factors, const TfSquareFreeResult &square_free, ComputationContext &context)
定义
univariate_factor_bridge.cpp:114
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_lift_and_combine
UnivariateFactorResult bridge_lift_and_combine(const Polynomial< Rational > &original, const Polynomial< Rational > &work, BerlekampResult &reduction, ComputationContext &context, bool &whole_input)
定义
univariate_factor_bridge.cpp:78
LMCAS::anonymous_namespace{univariate_factor_bridge.cpp}::bridge_inconclusive_error
bool bridge_inconclusive_error(const CasError &error)
定义
univariate_factor_bridge.cpp:74
LMCAS
定义
assumption.hpp:11
LMCAS::tf_square_free
TfSquareFreeResult tf_square_free(const Polynomial< Rational > &poly)
计算多项式的无平方因子部分,用于 Berlekamp 模分解预处理。
定义
rational_square_free.cpp:67
LMCAS::factor_integer_polynomial
Polynomial< BigInt > factor_integer_polynomial(const Polynomial< Rational > &polynomial)
定义
univariate_factor_bridge.cpp:9
LMCAS::Completeness::Inconclusive
@ Inconclusive
定义
result.hpp:122
LMCAS::Completeness::Complete
@ Complete
定义
result.hpp:122
LMCAS::context
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
定义
exact_factorization.hpp:65
LMCAS::UnivariateFactorResult
Result< MathResult< std::vector< Polynomial< Rational > > > > UnivariateFactorResult
定义
multivariate_factor_support.hpp:9
LMCAS::hensel_lift_checked
HenselLiftResult hensel_lift_checked(const Polynomial< BigInt > &poly, const std::vector< Polynomial< ModInt > > &mod_factors, int64_t prime, int lift_bound)
Hensel 提升:将模 p 因子提升到 mod p^k.
定义
hensel_lift.cpp:695
LMCAS::CasErrc::Inconclusive
@ Inconclusive
定义
result.hpp:24
LMCAS::CasErrc::InvalidArgument
@ InvalidArgument
定义
result.hpp:13
LMCAS::CasErrc::InternalInvariant
@ InternalInvariant
定义
result.hpp:28
LMCAS::CasErrc::ResourceLimit
@ ResourceLimit
定义
result.hpp:25
LMCAS::MathResult::value
T value
定义
result.hpp:126
LMCAS::berlekamp_factor
BerlekampResult berlekamp_factor(const Polynomial< Rational > &poly, int64_t prime)
定义
berlekamp.cpp:31
LMCAS::factor_univariate_bridge_checked
UnivariateFactorResult factor_univariate_bridge_checked(const Polynomial< Rational > &polynomial, ComputationContext &context)
定义
univariate_factor_bridge.cpp:166
LMCAS::target
const ExprPtr & target
定义
expr.hpp:317
LMCAS::unit
const std::string & unit
定义
expr.hpp:163
LMCAS::prime
int64_t prime
定义
exact_factorization.hpp:38
LMCAS::CasError::code
CasErrc code
定义
result.hpp:32
LMCAS::zassenhaus_combine_checked
ZassenhausResult zassenhaus_combine_checked(const Polynomial< Rational > &poly, const std::vector< Polynomial< BigInt > > &lifted_factors, const BigInt &reconstruction_modulus, ComputationContext &context)
定义
zassenhaus_combine.cpp:455
LMCAS::MathResult
定义
result.hpp:125
LMCAS::CasError
定义
result.hpp:31
LMCAS::BerlekampResult
Berlekamp 分解结果。
定义
exact_factorization.hpp:15
LMCAS::BerlekampResult::factors
std::vector< Polynomial< ModInt > > factors
模 p 下的不可约因子。
定义
exact_factorization.hpp:17
LMCAS::BerlekampResult::prime
int64_t prime
使用的素数。
定义
exact_factorization.hpp:16
LMCAS::TfSquareFreeResult
执行一步二次 Hensel 提升:mod m -> mod m^2.
定义
exact_factorization.hpp:111
LMCAS::TfSquareFreeResult::repeated_factor
Polynomial< Rational > repeated_factor
重复因子 gcd(f, f')。
定义
exact_factorization.hpp:113
LMCAS::TfSquareFreeResult::had_repeated_factors
bool had_repeated_factors
是否存在重复因子。
定义
exact_factorization.hpp:114
src
univariate_factor_bridge.cpp
生成于
, 为 LMCAS使用
1.18.0