LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
univariate_factor_bridge.cpp
浏览该文件的文档.
3#include <exception>
4#include <iterator>
5#include <new>
6#include <utility>
7
8namespace LMCAS {
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}
23namespace {
24
25constexpr const char* bridge_operation = "factor_univariate";
26
33
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 }
48}
49
50
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) {
69 "提升次数上限不足以保证重构", bridge_operation);
70 }
71 return Result<int>::success(bound);
72}
73
75 return error.code == CasErrc::InvalidArgument || error.code == CasErrc::Inconclusive;
76}
77
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
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
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 }
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())) {
159 "一元因子未能精确重构输入多项式", bridge_operation);
160 }
161 return UnivariateFactorResult::success(std::move(factors));
162}
163
164}
165
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) {
172 MathResult<std::vector<Polynomial<Rational>>>{
173 poly.is_zero() ? std::vector<Polynomial<Rational>>{}
174 : std::vector<Polynomial<Rational>>{poly},
176 }
177 if (poly.degree() == 1) {
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&) {
186 CasErrc::ResourceLimit, "一元分解分配失败", bridge_operation);
187 } catch (const std::exception& error) {
189 CasErrc::InternalInvariant, error.what(), bridge_operation);
190 }
191}
192
193}
模整数类,封装模 p 下的算术运算
一元多项式模板类
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
int degree() const
获取多项式的次数
Polynomial make_monic() const
首一化(使首项系数为 1)
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(MathResult< std::vector< Polynomial< Rational > > > value)
Result< int > bridge_lift_bound(const Polynomial< BigInt > &poly, int64_t prime, BigInt &modulus, ComputationContext &context)
Result< BerlekampResult > bridge_reduction(const Polynomial< Rational > &poly, ComputationContext &context)
UnivariateFactorResult bridge_inconclusive(const Polynomial< Rational > &poly, const char *reason)
UnivariateFactorResult bridge_factor(const Polynomial< Rational > &poly, ComputationContext &context)
Result< void > bridge_append_repeated(MathResult< std::vector< Polynomial< Rational > > > &factors, const TfSquareFreeResult &square_free, ComputationContext &context)
UnivariateFactorResult bridge_lift_and_combine(const Polynomial< Rational > &original, const Polynomial< Rational > &work, BerlekampResult &reduction, ComputationContext &context, bool &whole_input)
TfSquareFreeResult tf_square_free(const Polynomial< Rational > &poly)
计算多项式的无平方因子部分,用于 Berlekamp 模分解预处理。
Polynomial< BigInt > factor_integer_polynomial(const Polynomial< Rational > &polynomial)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
Result< MathResult< std::vector< Polynomial< Rational > > > > UnivariateFactorResult
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.
BerlekampResult berlekamp_factor(const Polynomial< Rational > &poly, int64_t prime)
UnivariateFactorResult factor_univariate_bridge_checked(const Polynomial< Rational > &polynomial, ComputationContext &context)
const ExprPtr & target
const std::string & unit
ZassenhausResult zassenhaus_combine_checked(const Polynomial< Rational > &poly, const std::vector< Polynomial< BigInt > > &lifted_factors, const BigInt &reconstruction_modulus, ComputationContext &context)
Berlekamp 分解结果。
std::vector< Polynomial< ModInt > > factors
模 p 下的不可约因子。
int64_t prime
使用的素数。
执行一步二次 Hensel 提升:mod m -> mod m^2.
Polynomial< Rational > repeated_factor
重复因子 gcd(f, f')。
bool had_repeated_factors
是否存在重复因子。