40 if (k < 0 || k > n)
return BigInt(0);
41 if (k == 0 || k == n)
return BigInt(1);
49 for (
int i = 0; i < k; ++i) {
50 result = result * BigInt(n - i);
51 result = result / BigInt(i + 1);
67 for (
const auto&
c : poly.
coeffs) {
93 if (n <= 0)
return BigInt(1);
102 BigInt b_squared = binom * binom * norm_sq;
106 BigInt
b = b_squared.sqrt();
107 if (
b *
b < b_squared) {
136 BigInt threshold = BigInt(2) * B * lc;
140 BigInt big_p(
static_cast<std::int64_t
>(
prime));
143 while (p_power <= threshold) {
144 p_power = p_power * big_p;
165 for (
auto&
c : poly) {
169 while (!poly.empty() && poly.back().is_zero()) {
186 const std::vector<BigInt>&
b,
188 if (
a.empty() ||
b.empty())
return {};
190 size_t n =
a.size() +
b.size() - 1;
191 std::vector<BigInt> result(n, BigInt(0));
193 for (
size_t i = 0; i <
a.size(); ++i) {
194 if (
a[i].is_zero())
continue;
195 for (
size_t j = 0; j <
b.size(); ++j) {
196 if (
b[j].is_zero())
continue;
197 result[i + j] = result[i + j] +
a[i] *
b[j];
215 const std::vector<BigInt>&
b,
217 size_t n = std::max(
a.size(),
b.size());
218 std::vector<BigInt> result(n, BigInt(0));
220 for (
size_t i = 0; i < n; ++i) {
221 BigInt ai = (i <
a.size()) ?
a[i] : BigInt(0);
222 BigInt bi = (i <
b.size()) ?
b[i] : BigInt(0);
240 const std::vector<BigInt>&
b,
242 size_t n = std::max(
a.size(),
b.size());
243 std::vector<BigInt> result(n, BigInt(0));
245 for (
size_t i = 0; i < n; ++i) {
246 BigInt ai = (i <
a.size()) ?
a[i] : BigInt(0);
247 BigInt bi = (i <
b.size()) ?
b[i] : BigInt(0);
269 BigInt r0 = m, r1 =
a % m;
270 if (r1.is_negative()) r1 = r1 + m;
274 while (!r1.is_zero()) {
276 BigInt r_new = r0 - q * r1;
277 BigInt s_new = s0 - q * s1;
286 if (r0 != BigInt(1) && r0 != BigInt(-1)) {
287 throw std::domain_error(
"hl_mod_inverse: element not invertible");
291 if (r0.is_negative()) {
295 BigInt result = s0 % m;
296 if (result.is_negative()) result = result + m;
313static std::pair<std::vector<BigInt>, std::vector<BigInt>>
315 const std::vector<BigInt>&
b,
318 throw std::runtime_error(
"hl_poly_divmod: division by zero polynomial");
321 int deg_a =
static_cast<int>(
a.size()) - 1;
322 int deg_b =
static_cast<int>(
b.size()) - 1;
325 std::vector<BigInt>
r =
a;
333 std::vector<BigInt> remainder =
a;
334 std::vector<BigInt> quotient(deg_a - deg_b + 1, BigInt(0));
336 for (
int i = deg_a; i >= deg_b; --i) {
338 if (coeff.is_zero())
continue;
341 quotient[i - deg_b] = factor;
343 for (
int j = 0; j <= deg_b; ++j) {
344 remainder[i - deg_b + j] = remainder[i - deg_b + j] - factor *
b[j];
345 remainder[i - deg_b + j] =
351 std::vector<BigInt> rem(remainder.begin(), remainder.begin() + deg_b);
354 return {quotient, rem};
358 if (
value < 2)
return false;
359 if (
value == 2)
return true;
360 if (
value % 2 == 0)
return false;
361 for (int64_t divisor = 3; divisor <=
value / divisor; divisor += 2) {
362 if (
value % divisor == 0)
return false;
368 std::vector<BigInt>
right) {
369 while (!left.empty() && left.back().is_zero()) left.pop_back();
371 const std::size_t size = std::max(left.size(),
right.size());
372 left.resize(size, BigInt(0));
373 right.resize(size, BigInt(0));
374 return left ==
right;
379 const std::vector<std::vector<BigInt>>& factor_vecs,
381 constexpr const char* operation =
"hensel_lift";
384 "Hensel lifting requires a prime modulus",
389 "Hensel lifting requires a non-constant polynomial",
392 if (factor_vecs.empty()) {
394 "Hensel lifting requires at least one mod-p factor",
397 for (
const auto& factor : factor_vecs) {
398 if (factor.empty()) {
400 "Hensel lifting factor cannot be zero",
405 const BigInt modulus(
static_cast<std::int64_t
>(
prime));
406 std::vector<BigInt> product{BigInt(1)};
407 for (
const auto& factor : factor_vecs) {
410 std::vector<BigInt> reduced_f = poly.
coeffs;
414 "mod-p factors do not multiply to the input polynomial",
451 const std::vector<BigInt>& f,
454 const auto& g = current.
g;
455 const auto& h = current.
h;
456 const auto& s = current.
s;
457 const auto&
t = current.
t;
458 const BigInt& m = current.
modulus;
491 std::vector<BigInt> one_poly = {BigInt(1)};
525static std::pair<std::vector<BigInt>, std::vector<BigInt>>
527 const std::vector<BigInt>& h,
531 std::vector<BigInt> r0 = g, r1 = h;
532 std::vector<BigInt> s0 = {BigInt(1)}, s1 = {};
533 std::vector<BigInt> t0 = {}, t1 = {BigInt(1)};
535 while (!r1.empty()) {
539 std::vector<BigInt> r_new =
r;
556 if (!r0.empty() && r0[0] != BigInt(1)) {
567 while (!s0.empty() && s0.back().is_zero()) s0.pop_back();
568 while (!t0.empty() && t0.back().is_zero()) t0.pop_back();
598 const std::vector<BigInt>& f,
599 const std::vector<std::vector<BigInt>>& factors,
603 if (factors.empty())
return {};
604 if (factors.size() == 1) {
606 BigInt target_mod(1);
607 BigInt big_p(
static_cast<std::int64_t
>(
prime));
608 for (
int i = 0; i < target_k; ++i) {
609 target_mod = target_mod * big_p;
611 std::vector<BigInt> result = f;
616 BigInt big_p(
static_cast<std::int64_t
>(
prime));
617 BigInt initial_mod(
static_cast<std::int64_t
>(
prime));
620 BigInt target_mod(1);
621 for (
int i = 0; i < target_k; ++i) {
622 target_mod = target_mod * big_p;
630 std::vector<BigInt> remaining = f;
634 std::vector<std::vector<BigInt>> remaining_factors = factors;
636 for (
size_t i = 0; i < factors.size() - 1; ++i) {
638 std::vector<BigInt> g = remaining_factors[0];
641 std::vector<BigInt> h = remaining_factors[1];
642 for (
size_t j = 2; j < remaining_factors.size(); ++j) {
653 while (state.
modulus < target_mod) {
658 std::vector<BigInt> lifted_g = state.
g;
667 remaining_factors.erase(remaining_factors.begin());
700 constexpr const char* operation =
"hensel_lift";
703 std::vector<BigInt> f_vec = poly.
coeffs;
706 std::vector<std::vector<BigInt>> factor_vecs;
709 std::vector<BigInt> fv;
710 fv.reserve(mf.coeffs.size());
711 for (
const auto&
c : mf.coeffs) {
712 fv.push_back(BigInt(
static_cast<std::int64_t
>(
c.value())));
714 factor_vecs.push_back(std::move(fv));
727 std::vector<std::vector<BigInt>> lifted_vecs;
730 }
catch (
const std::exception& ex) {
737 std::vector<Polynomial<BigInt>> result;
738 result.reserve(lifted_vecs.size());
739 for (
auto& lv : lifted_vecs) {
std::string variable_name
变量名
bool is_zero() const
判断是否为零多项式
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
CoeffType lead_coeff() const
获取首项系数
int degree() const
获取多项式的次数
static Result failure(CasErrc code, std::string message, std::string operation={})
static Result success(T value)
BigInt symmetric_remainder(const BigInt &value, const BigInt &modulus)
static BigInt hl_mignotte_bound(const Polynomial< BigInt > &poly)
计算多项式的 Mignotte 界.
static bool hl_is_prime(int64_t value)
static int hl_compute_lift_height(const Polynomial< BigInt > &poly, int64_t prime)
计算 Hensel 提升所需的高度 k.
__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
static std::vector< BigInt > hl_poly_add_mod(const std::vector< BigInt > &a, const std::vector< BigInt > &b, const BigInt &m)
多项式加法(BigInt 系数),结果模 m 归约.
std::vector< BigInt > g
第一个因子的系数。
static void hl_reduce_coeffs(std::vector< BigInt > &poly, const BigInt &m)
对多项式系数向量执行模归约(对称表示).
static Result< void > hl_validate_lift_inputs(const Polynomial< BigInt > &poly, const std::vector< std::vector< BigInt > > &factor_vecs, int64_t prime)
const VectorField const VectorField & c
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.
static std::vector< BigInt > hl_poly_sub_mod(const std::vector< BigInt > &a, const std::vector< BigInt > &b, const BigInt &m)
多项式减法(BigInt 系数),结果模 m 归约.
static bool hl_coeff_vectors_equal(std::vector< BigInt > left, std::vector< BigInt > right)
static BigInt hl_mod_inverse(const BigInt &a, const BigInt &m)
计算 BigInt 在模 m 下的乘法逆元.
Result< std::vector< Polynomial< BigInt > > > HenselLiftResult
const std::vector< Polynomial< BigInt > > & lifted_factors
__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
static std::vector< std::vector< BigInt > > hl_multi_factor_lift(const std::vector< BigInt > &f, const std::vector< std::vector< BigInt > > &factors, int64_t prime, int target_k)
多因子 Hensel 提升:将 k 个模 p 因子同时提升到 mod p^target_k.
static std::pair< std::vector< BigInt >, std::vector< BigInt > > hl_extended_gcd_poly(const std::vector< BigInt > &g, const std::vector< BigInt > &h, const BigInt &m)
计算两个多项式在模 m 下的扩展 GCD 的 Bezout 系数.
HenselLiftPair hl_two_factor_lift(const std::vector< BigInt > &f, const HenselLiftPair ¤t)
执行一步二次 Hensel 提升:mod m -> mod m^2.
std::vector< BigInt > t
h 的 Bezout 系数。
const std::vector< Polynomial< ModInt > > & mod_factors
static std::pair< std::vector< BigInt >, std::vector< BigInt > > hl_poly_divmod(const std::vector< BigInt > &a, const std::vector< BigInt > &b, const BigInt &m)
多项式带余除法(BigInt 系数),模 m 下运算.
std::vector< BigInt > h
第二个因子的系数。
const std::string const ExprPtr & value
std::vector< BigInt > s
g 的 Bezout 系数。
static BigInt hl_binomial(int n, int k)
计算二项式系数 C(n, k).
__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 & t
static std::vector< BigInt > hl_poly_mul_mod(const std::vector< BigInt > &a, const std::vector< BigInt > &b, const BigInt &m)
多项式乘法(BigInt 系数),结果模 m 归约.
const std::vector< Polynomial< ModInt > > int64_t int lift_bound
static BigInt hl_l2_norm_squared(const Polynomial< BigInt > &poly)
计算多项式系数的 L2 范数的平方.