LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::berlekamp_detail 命名空间参考

函数

std::vector< std::vector< int64_t > > bk_build_q_matrix (const std::vector< int64_t > &f, int64_t p)
 构造 F_p 上的 Berlekamp 矩阵 Q。
static std::vector< int64_t > bk_derivative_mod (const std::vector< int64_t > &f, int64_t p)
 计算模 p 多项式的形式导数.
void bk_div_mod (const std::vector< int64_t > &a, const std::vector< int64_t > &b, int64_t p, std::vector< int64_t > &q, std::vector< int64_t > &r)
 模 p 多项式带余除法.
static void bk_eliminate_column (std::vector< std::vector< int64_t > > &matrix, int current_row, int col, int64_t p)
std::vector< int64_t > bk_gcd_mod (std::vector< int64_t > a, std::vector< int64_t > b, int64_t p)
 计算两个模 p 多项式的最大公因式.
static bool bk_is_square_free_mod (const std::vector< int64_t > &f, int64_t p)
 检查模 p 多项式是否为 无平方因子.
bool bk_is_suitable_prime (const Polynomial< Rational > &poly, int64_t prime)
 判断素数是否保持多项式次数和无平方性质。
int64_t bk_mod_inverse (int64_t a, int64_t p)
 模 p 下求乘法逆元.
std::vector< std::vector< int64_t > > bk_null_space (const std::vector< std::vector< int64_t > > &Q, int64_t p)
static std::vector< int64_t > bk_poly_mul_mod (const std::vector< int64_t > &a, const std::vector< int64_t > &b, const std::vector< int64_t > &f, int64_t p)
 在 F_p 上计算 a(x) * b(x) mod f(x)。
static std::vector< int64_t > bk_poly_pow_mod (const std::vector< int64_t > &base, int64_t exp, const std::vector< int64_t > &f, int64_t p)
 在 F_p 上用平方乘法计算 base^exp mod f(x)。
static void bk_reduce_matrix (std::vector< std::vector< int64_t > > &M, int64_t p, std::vector< int > &pivot_col, std::vector< int > &pivot_row)
std::vector< int64_t > bk_reduce_to_mod_coeffs (const Polynomial< Rational > &poly, int64_t p)
 以系数分母的 LCM 清除分母,再逐项取模 p。
int64_t bk_select_prime (const Polynomial< Rational > &poly)
 从小素数表中选取适合 Berlekamp 分解的素数。
std::vector< std::vector< int64_t > > bk_split_factors (const std::vector< int64_t > &f_coeffs, const std::vector< std::vector< int64_t > > &null_basis, int null_dim, int64_t p)
static bool bk_split_one_factor (std::vector< std::vector< int64_t > > &factor_list, size_t fi, const std::vector< int64_t > &v_poly, int null_dim, int64_t p)

变量

static constexpr size_t BK_NUM_SMALL_PRIMES
static constexpr int64_t BK_SMALL_PRIMES []
 Berlekamp 模分解的小素数候选表。 按升序选取首个不整除首项系数且使模约化结果无平方因子的素数。

函数说明

◆ bk_build_q_matrix()

std::vector< std::vector< int64_t > > LMCAS::berlekamp_detail::bk_build_q_matrix ( const std::vector< int64_t > & f,
int64_t p )

构造 F_p 上的 Berlekamp 矩阵 Q。

对次数为 n 的首一多项式 f,Q 的第 i 行为 x^(i*p) mod f(x) 的系数向量。 先用平方乘法求 h = x^p mod f,再由第 0 行 [1, 0, ..., 0] 逐行乘 h 并取余。

参数
[in]f首一多项式系数向量(升幂排列,deg(f) = n)
[in]p素数模数
返回
nxn Berlekamp 矩阵(行优先存储)
参见
Berlekamp, E.R. "Factoring polynomials over finite fields." Bell System Technical Journal, 46(8), 1967.

< f 的次数。

在文件 berlekamp_basis.cpp 第 106 行定义.

108 {
109
110 int n = static_cast<int>(f.size()) - 1; /**< f 的次数。 */
111
112 std::vector<std::vector<int64_t>> Q(n, std::vector<int64_t>(n, 0));
113
114 if (n <= 0) {
115 return Q;
116 }
117 Q[0][0] = 1;
118
119 if (n == 1) {
120 return Q;
121 }
122 std::vector<int64_t> x_poly = {0, 1};
123 std::vector<int64_t> h = bk_poly_pow_mod(x_poly, p, f, p);
124 for (size_t j = 0; j < h.size() && j < static_cast<size_t>(n); ++j) {
125 Q[1][j] = h[j];
126 }
127 std::vector<int64_t> current = h;
128 for (int i = 2; i < n; ++i) {
129 current = bk_poly_mul_mod(current, h, f, p);
130 for (size_t j = 0; j < current.size() && j < static_cast<size_t>(n); ++j) {
131 Q[i][j] = current[j];
132 }
133 }
134
135 return Q;
136}
static std::vector< int64_t > bk_poly_mul_mod(const std::vector< int64_t > &a, const std::vector< int64_t > &b, const std::vector< int64_t > &f, int64_t p)
在 F_p 上计算 a(x) * b(x) mod f(x)。
static std::vector< int64_t > bk_poly_pow_mod(const std::vector< int64_t > &base, int64_t exp, const std::vector< int64_t > &f, int64_t p)
在 F_p 上用平方乘法计算 base^exp mod f(x)。

引用了 bk_build_q_matrix(), bk_poly_mul_mod() , 以及 bk_poly_pow_mod().

被这些函数引用 LMCAS::berlekamp_factor() , 以及 bk_build_q_matrix().

函数调用图:
这是这个函数的调用关系图:

◆ bk_derivative_mod()

std::vector< int64_t > LMCAS::berlekamp_detail::bk_derivative_mod ( const std::vector< int64_t > & f,
int64_t p )
static

计算模 p 多项式的形式导数.

参数
[in]f模 p 系数向量
[in]p素数模数
返回
f' 的系数向量

在文件 berlekamp_modular.cpp 第 76 行定义.

78 {
79
80 if (f.size() <= 1) {
81 return {};
82 }
83
84 std::vector<int64_t> deriv;
85 deriv.reserve(f.size() - 1);
86
87 for (size_t i = 1; i < f.size(); ++i) {
88 const auto index_residue = static_cast<std::int64_t>(
89 i % static_cast<std::uint64_t>(p));
90 int64_t coeff = (f[i] * index_residue) % p;
91 deriv.push_back(coeff);
92 }
93
94 while (!deriv.empty() && deriv.back() == 0) {
95 deriv.pop_back();
96 }
97
98 return deriv;
99}

引用了 bk_derivative_mod().

被这些函数引用 bk_derivative_mod() , 以及 bk_is_square_free_mod().

函数调用图:
这是这个函数的调用关系图:

◆ bk_div_mod()

void LMCAS::berlekamp_detail::bk_div_mod ( const std::vector< int64_t > & a,
const std::vector< int64_t > & b,
int64_t p,
std::vector< int64_t > & q,
std::vector< int64_t > & r )

模 p 多项式带余除法.

计算 a / b 的商和余数,使得 a = q * b + r,deg(r) < deg(b).

参数
[in]a被除数系数向量
[in]b除数系数向量(非空)
[in]p素数模数
[out]q商系数向量
[out]r余数系数向量

在文件 berlekamp_modular.cpp 第 129 行定义.

134 {
135
136 q.clear();
137 r = a;
138
139 if (b.empty()) return;
140
141 int deg_b = static_cast<int>(b.size()) - 1;
142 int64_t lc_b_inv = bk_mod_inverse(b.back(), p);
143
144 int deg_r = static_cast<int>(r.size()) - 1;
145
146 if (deg_r < deg_b) {
147 return;
148 }
149
150 q.resize(deg_r - deg_b + 1, 0);
151
152 while (deg_r >= deg_b) {
153 int64_t factor = (r[deg_r] * lc_b_inv) % p;
154 int shift = deg_r - deg_b;
155 q[shift] = factor;
156
157 for (int i = 0; i <= deg_b; ++i) {
158 r[shift + i] = (r[shift + i] - factor * b[i] % p + p) % p;
159 }
160
161 while (deg_r >= 0 && r[deg_r] == 0) {
162 r.pop_back();
163 deg_r--;
164 }
165 }
166}
int64_t bk_mod_inverse(int64_t a, int64_t p)
模 p 下求乘法逆元.
__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
const MultiPoly & b
__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

引用了 LMCAS::a, LMCAS::b, bk_div_mod(), bk_mod_inverse() , 以及 LMCAS::r.

被这些函数引用 bk_div_mod(), bk_gcd_mod(), bk_poly_mul_mod(), bk_poly_pow_mod() , 以及 bk_split_one_factor().

函数调用图:
这是这个函数的调用关系图:

◆ bk_eliminate_column()

void LMCAS::berlekamp_detail::bk_eliminate_column ( std::vector< std::vector< int64_t > > & matrix,
int current_row,
int col,
int64_t p )
static

在文件 berlekamp_basis.cpp 第 138 行定义.

139 {
140 const int n = static_cast<int>(matrix.size());
141 int64_t inverse = bk_mod_inverse(matrix[current_row][col], p);
142 for (int j = 0; j < n; ++j) {
143 matrix[current_row][j] = (matrix[current_row][j] * inverse) % p;
144 }
145 for (int row = 0; row < n; ++row) {
146 if (row == current_row) continue;
147 int64_t factor = matrix[row][col];
148 if (factor == 0) continue;
149 for (int j = 0; j < n; ++j) {
150 matrix[row][j] =
151 (matrix[row][j] - factor * matrix[current_row][j] % p + p) % p;
152 }
153 }
154}

引用了 bk_eliminate_column() , 以及 bk_mod_inverse().

被这些函数引用 bk_eliminate_column() , 以及 bk_reduce_matrix().

函数调用图:
这是这个函数的调用关系图:

◆ bk_gcd_mod()

std::vector< int64_t > LMCAS::berlekamp_detail::bk_gcd_mod ( std::vector< int64_t > a,
std::vector< int64_t > b,
int64_t p )

计算两个模 p 多项式的最大公因式.

使用欧几里得算法.结果为首一多项式.

参数
[in]a第一个多项式系数向量
[in]b第二个多项式系数向量
[in]p素数模数
返回
gcd(a, b) 的首一化系数向量

在文件 berlekamp_modular.cpp 第 179 行定义.

182 {
183
184 while (!b.empty()) {
185 std::vector<int64_t> q, r;
186 bk_div_mod(a, b, p, q, r);
187 a = std::move(b);
188 b = std::move(r);
189 }
190
191 if (!a.empty()) {
192 int64_t lc_inv = bk_mod_inverse(a.back(), p);
193 for (auto& c : a) {
194 c = (c * lc_inv) % p;
195 }
196 }
197
198 return a;
199}
void bk_div_mod(const std::vector< int64_t > &a, const std::vector< int64_t > &b, int64_t p, std::vector< int64_t > &q, std::vector< int64_t > &r)
模 p 多项式带余除法.
const VectorField const VectorField & c

引用了 LMCAS::a, LMCAS::b, bk_div_mod(), bk_gcd_mod(), bk_mod_inverse(), LMCAS::c , 以及 LMCAS::r.

被这些函数引用 bk_gcd_mod(), bk_is_square_free_mod() , 以及 bk_split_one_factor().

函数调用图:
这是这个函数的调用关系图:

◆ bk_is_square_free_mod()

bool LMCAS::berlekamp_detail::bk_is_square_free_mod ( const std::vector< int64_t > & f,
int64_t p )
static

检查模 p 多项式是否为 无平方因子.

多项式 f 在 F_p 上 无平方因子 当且仅当 gcd(f, f') 的次数为 0.

参数
[in]f模 p 系数向量
[in]p素数模数
返回
f 为 无平方因子 返回 true

在文件 berlekamp_modular.cpp 第 211 行定义.

213 {
214
215 if (f.size() <= 1) return true;
216
217 std::vector<int64_t> f_prime = bk_derivative_mod(f, p);
218 if (f_prime.empty()) return false;
219
220 std::vector<int64_t> g = bk_gcd_mod(f, f_prime, p);
221 return g.size() <= 1;
222}
std::vector< int64_t > bk_gcd_mod(std::vector< int64_t > a, std::vector< int64_t > b, int64_t p)
计算两个模 p 多项式的最大公因式.
static std::vector< int64_t > bk_derivative_mod(const std::vector< int64_t > &f, int64_t p)
计算模 p 多项式的形式导数.

引用了 bk_derivative_mod(), bk_gcd_mod() , 以及 bk_is_square_free_mod().

被这些函数引用 bk_is_square_free_mod() , 以及 bk_is_suitable_prime().

函数调用图:
这是这个函数的调用关系图:

◆ bk_is_suitable_prime()

bool LMCAS::berlekamp_detail::bk_is_suitable_prime ( const Polynomial< Rational > & poly,
int64_t prime )

判断素数是否保持多项式次数和无平方性质。

Berlekamp 分解要求模约化仍位于同一次数的多项式环中,并且 gcd(f mod p, f' mod p) 为常数。显式和自动素数选择共用此检查。

参数
[in]poly非零有理系数多项式,次数 >= 1。
[in]prime候选模数。
返回
候选为内核支持的素数且满足分解前置条件时返回 true。

在文件 berlekamp_modular.cpp 第 235 行定义.

237 {
238 if (poly.is_zero() || poly.degree() < 1 ||
239 prime < 2 ||
240 prime > std::numeric_limits<std::int64_t>::max() / prime ||
241 !lmmp_is_prime_ulong_(static_cast<ulong>(prime))) {
242 return false;
243 }
244
245 auto reduced = bk_reduce_to_mod_coeffs(poly, prime);
246 if (static_cast<int>(reduced.size()) - 1 != poly.degree()) {
247 return false;
248 }
249 return bk_is_square_free_mod(reduced, prime);
250}
bool is_zero() const
判断是否为零多项式
int degree() const
获取多项式的次数
static bool bk_is_square_free_mod(const std::vector< int64_t > &f, int64_t p)
检查模 p 多项式是否为 无平方因子.
std::vector< int64_t > bk_reduce_to_mod_coeffs(const Polynomial< Rational > &poly, int64_t p)
以系数分母的 LCM 清除分母,再逐项取模 p。

引用了 bk_is_square_free_mod(), bk_is_suitable_prime(), bk_reduce_to_mod_coeffs(), LMCAS::Polynomial< CoeffType >::degree(), LMCAS::Polynomial< CoeffType >::is_zero() , 以及 LMCAS::prime.

被这些函数引用 LMCAS::berlekamp_factor(), bk_is_suitable_prime() , 以及 bk_select_prime().

函数调用图:
这是这个函数的调用关系图:

◆ bk_mod_inverse()

int64_t LMCAS::berlekamp_detail::bk_mod_inverse ( int64_t a,
int64_t p )

模 p 下求乘法逆元.

使用扩展欧几里得算法计算 a^(-1) mod p.

参数
[in]a待求逆的值(非零)
[in]p素数模数
返回
a 在模 p 下的逆元

在文件 berlekamp_modular.cpp 第 111 行定义.

111 {
112 int64_t s, t;
113 extended_gcd(((a % p) + p) % p, p, s, t);
114 return ((s % p) + p) % p;
115}
__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
int64_t extended_gcd(int64_t a, int64_t b, int64_t &s, int64_t &t)
用扩展欧几里得算法求 gcd(a,b) 及 Bezout 系数。

引用了 LMCAS::a, bk_mod_inverse(), LMCAS::extended_gcd() , 以及 LMCAS::t.

被这些函数引用 LMCAS::berlekamp_factor(), bk_div_mod(), bk_eliminate_column(), bk_gcd_mod() , 以及 bk_mod_inverse().

函数调用图:
这是这个函数的调用关系图:

◆ bk_null_space()

std::vector< std::vector< int64_t > > LMCAS::berlekamp_detail::bk_null_space ( const std::vector< std::vector< int64_t > > & Q,
int64_t p )

< 当前自由变量取 1,其余自由变量取 0。

由行简化阶梯形回代约束分量。 M[row][pc] = 1,故 x[pc] + sum_{自由列 j} M[row][j] * x[j] = 0, 当前基向量满足 x[pc] = -M[row][col] mod p。

在文件 berlekamp_basis.cpp 第 184 行定义.

186 {
187
188 int n = static_cast<int>(Q.size());
189 if (n == 0) {
190 return {};
191 }
192 std::vector<std::vector<int64_t>> M(n, std::vector<int64_t>(n, 0));
193 for (int i = 0; i < n; ++i) {
194 for (int j = 0; j < n; ++j) {
195 int64_t val = Q[j][i];
196 if (i == j) {
197 val = (val - 1 + p) % p;
198 }
199 M[i][j] = val;
200 }
201 }
202 std::vector<int> pivot_col(n, -1);
203 std::vector<int> pivot_row(n, -1);
204
205 bk_reduce_matrix(M, p, pivot_col, pivot_row);
206 std::vector<std::vector<int64_t>> basis;
207
208 for (int col = 0; col < n; ++col) {
209 if (pivot_row[col] != -1) {
210 continue;
211 }
212
213 std::vector<int64_t> vec(n, 0);
214 vec[col] = 1; /**< 当前自由变量取 1,其余自由变量取 0。 */
215
216 for (int row = 0; row < n; ++row) {
217 int pc = pivot_col[row];
218 if (pc == -1) continue;
219 /**
220 * @brief 由行简化阶梯形回代约束分量。
221 * M[row][pc] = 1,故 x[pc] + sum_{自由列 j} M[row][j] * x[j] = 0,
222 * 当前基向量满足 x[pc] = -M[row][col] mod p。
223 */
224 vec[pc] = (p - M[row][col]) % p;
225 }
226
227 basis.push_back(std::move(vec));
228 }
229
230 return basis;
231}
static void bk_reduce_matrix(std::vector< std::vector< int64_t > > &M, int64_t p, std::vector< int > &pivot_col, std::vector< int > &pivot_row)
const std::vector< FGLMPoly > & basis

引用了 LMCAS::basis, bk_null_space() , 以及 bk_reduce_matrix().

被这些函数引用 LMCAS::berlekamp_factor() , 以及 bk_null_space().

函数调用图:
这是这个函数的调用关系图:

◆ bk_poly_mul_mod()

std::vector< int64_t > LMCAS::berlekamp_detail::bk_poly_mul_mod ( const std::vector< int64_t > & a,
const std::vector< int64_t > & b,
const std::vector< int64_t > & f,
int64_t p )
static

在 F_p 上计算 a(x) * b(x) mod f(x)。

参数
[in]a第一个多项式系数向量(升幂排列)
[in]b第二个多项式系数向量(升幂排列)
[in]f模多项式系数向量(首一,升幂排列)
[in]p素数模数
返回
a * b mod f 的系数向量

在文件 berlekamp_basis.cpp 第 17 行定义.

21 {
22
23 if (a.empty() || b.empty()) {
24 return {};
25 }
26 size_t prod_size = a.size() + b.size() - 1;
27 std::vector<int64_t> product(prod_size, 0);
28
29 for (size_t i = 0; i < a.size(); ++i) {
30 if (a[i] == 0) continue;
31 for (size_t j = 0; j < b.size(); ++j) {
32 product[i + j] = (product[i + j] + a[i] * b[j]) % p;
33 if (product[i + j] < 0) product[i + j] += p;
34 }
35 }
36
37 std::vector<int64_t> q, r;
38 bk_div_mod(product, f, p, q, r);
39
40 return r;
41}

引用了 LMCAS::a, LMCAS::b, bk_div_mod(), bk_poly_mul_mod() , 以及 LMCAS::r.

被这些函数引用 bk_build_q_matrix(), bk_poly_mul_mod() , 以及 bk_poly_pow_mod().

函数调用图:
这是这个函数的调用关系图:

◆ bk_poly_pow_mod()

std::vector< int64_t > LMCAS::berlekamp_detail::bk_poly_pow_mod ( const std::vector< int64_t > & base,
int64_t exp,
const std::vector< int64_t > & f,
int64_t p )
static

在 F_p 上用平方乘法计算 base^exp mod f(x)。

参数
[in]base底多项式系数向量(升幂排列)
[in]exp指数(非负整数)
[in]f模多项式系数向量(首一,升幂排列)
[in]p素数模数
返回
base^exp mod f 的系数向量
参见
Berlekamp, E.R. "Factoring polynomials over finite fields."

在文件 berlekamp_basis.cpp 第 55 行定义.

59 {
60
61 if (exp == 0) {
62 return {1};
63 }
64
65 if (exp == 1) {
66 std::vector<int64_t> q, r;
67 bk_div_mod(base, f, p, q, r);
68 return r;
69 }
70 std::vector<int64_t> result = {1};
71 std::vector<int64_t> cur = base;
72 {
73 std::vector<int64_t> q, r;
74 bk_div_mod(cur, f, p, q, r);
75 cur = std::move(r);
76 }
77
78 int64_t e = exp;
79 while (e > 0) {
80 if (e & 1) {
81 result = bk_poly_mul_mod(result, cur, f, p);
82 }
83 e >>= 1;
84 if (e > 0) {
85 cur = bk_poly_mul_mod(cur, cur, f, p);
86 }
87 }
88
89 return result;
90}
ExprResult exp(const ExprPtr &expression, ComputationContext &context)
ExprResult e()

引用了 bk_div_mod(), bk_poly_mul_mod(), bk_poly_pow_mod(), LMCAS::e(), LMCAS::exp() , 以及 LMCAS::r.

被这些函数引用 bk_build_q_matrix() , 以及 bk_poly_pow_mod().

函数调用图:
这是这个函数的调用关系图:

◆ bk_reduce_matrix()

void LMCAS::berlekamp_detail::bk_reduce_matrix ( std::vector< std::vector< int64_t > > & M,
int64_t p,
std::vector< int > & pivot_col,
std::vector< int > & pivot_row )
static

在文件 berlekamp_basis.cpp 第 156 行定义.

157 {
158 const int n = static_cast<int>(M.size());
159 int current_row = 0;
160 for (int col = 0; col < n && current_row < n; ++col) {
161 int pivot = -1;
162 for (int row = current_row; row < n; ++row) {
163 if (M[row][col] != 0) {
164 pivot = row;
165 break;
166 }
167 }
168
169 if (pivot == -1) {
170 continue;
171 }
172
173 if (pivot != current_row) {
174 std::swap(M[pivot], M[current_row]);
175 }
176
177 pivot_col[current_row] = col;
178 pivot_row[col] = current_row;
179 bk_eliminate_column(M, current_row, col, p);
180 ++current_row;
181 }
182}
static void bk_eliminate_column(std::vector< std::vector< int64_t > > &matrix, int current_row, int col, int64_t p)

引用了 bk_eliminate_column() , 以及 bk_reduce_matrix().

被这些函数引用 bk_null_space() , 以及 bk_reduce_matrix().

函数调用图:
这是这个函数的调用关系图:

◆ bk_reduce_to_mod_coeffs()

std::vector< int64_t > LMCAS::berlekamp_detail::bk_reduce_to_mod_coeffs ( const Polynomial< Rational > & poly,
int64_t p )

以系数分母的 LCM 清除分母,再逐项取模 p。

参数
[in]poly有理系数多项式
[in]p素数模数
返回
升幂排列的模 p 系数向量,去除高次零系数。

在文件 berlekamp_modular.cpp 第 29 行定义.

31 {
32
33 if (poly.is_zero()) {
34 return {};
35 }
36
37 BigInt lcm_den(1);
38 for (const auto& c : poly.coeffs) {
39 BigInt den = c.get_denominator();
40 BigInt g = BigInt::gcd(lcm_den, den);
41 lcm_den = lcm_den * (den / g);
42 }
43
44 BigInt big_p(static_cast<std::int64_t>(p));
45
46 std::vector<int64_t> mod_coeffs;
47 mod_coeffs.reserve(poly.coeffs.size());
48
49 for (const auto& c : poly.coeffs) {
50 BigInt num = c.get_numerator();
51 BigInt den = c.get_denominator();
52 BigInt integer_coeff = num * (lcm_den / den);
53
54 BigInt rem = integer_coeff % big_p;
55 int64_t rem_val = rem.try_to_int64().value();
56 if (rem_val < 0) rem_val += p;
57
58 mod_coeffs.push_back(rem_val);
59 }
60
61 while (!mod_coeffs.empty() && mod_coeffs.back() == 0) {
62 mod_coeffs.pop_back();
63 }
64
65 return mod_coeffs;
66}
std::vector< CoeffType > coeffs
系数数组,coeffs[i] 为 x^i 的系数
std::shared_ptr< SymbolicExpr > num(int value)

引用了 bk_reduce_to_mod_coeffs(), LMCAS::c, LMCAS::Polynomial< CoeffType >::coeffs, LMCAS::Polynomial< CoeffType >::is_zero() , 以及 LMCAS::polynomial_solver_detail::num().

被这些函数引用 LMCAS::berlekamp_factor(), bk_is_suitable_prime() , 以及 bk_reduce_to_mod_coeffs().

函数调用图:
这是这个函数的调用关系图:

◆ bk_select_prime()

int64_t LMCAS::berlekamp_detail::bk_select_prime ( const Polynomial< Rational > & poly)

从小素数表中选取适合 Berlekamp 分解的素数。

参数
[in]poly非零有理系数多项式,次数 >= 1。
返回
首个合适的素数 p;候选均不满足时返回 -1。

在文件 berlekamp_modular.cpp 第 258 行定义.

258 {
259 if (poly.is_zero() || poly.degree() < 1) {
260 return -1;
261 }
262 for (size_t i = 0; i < BK_NUM_SMALL_PRIMES; ++i) {
264 return BK_SMALL_PRIMES[i];
265 }
266 }
267 return -1;
268}
static constexpr int64_t BK_SMALL_PRIMES[]
Berlekamp 模分解的小素数候选表。 按升序选取首个不整除首项系数且使模约化结果无平方因子的素数。
static constexpr size_t BK_NUM_SMALL_PRIMES
bool bk_is_suitable_prime(const Polynomial< Rational > &poly, int64_t prime)
判断素数是否保持多项式次数和无平方性质。

引用了 bk_is_suitable_prime(), BK_NUM_SMALL_PRIMES, bk_select_prime(), BK_SMALL_PRIMES, LMCAS::Polynomial< CoeffType >::degree() , 以及 LMCAS::Polynomial< CoeffType >::is_zero().

被这些函数引用 LMCAS::berlekamp_factor() , 以及 bk_select_prime().

函数调用图:
这是这个函数的调用关系图:

◆ bk_split_factors()

std::vector< std::vector< int64_t > > LMCAS::berlekamp_detail::bk_split_factors ( const std::vector< int64_t > & f_coeffs,
const std::vector< std::vector< int64_t > > & null_basis,
int null_dim,
int64_t p )

在文件 berlekamp_split.cpp 第 40 行定义.

44 {
45
46 std::vector<std::vector<int64_t>> factor_list;
47 factor_list.push_back(f_coeffs);
48
49 for (const auto& basis_vec : null_basis) {
50 bool is_trivial = true;
51 if (!basis_vec.empty() && basis_vec[0] == 1) {
52 for (size_t i = 1; i < basis_vec.size(); ++i) {
53 if (basis_vec[i] != 0) {
54 is_trivial = false;
55 break;
56 }
57 }
58 } else {
59 is_trivial = false;
60 }
61 if (is_trivial) continue;
62
63 if (static_cast<int>(factor_list.size()) >= null_dim) break;
64 std::vector<int64_t> v_poly = basis_vec;
65 while (!v_poly.empty() && v_poly.back() == 0) {
66 v_poly.pop_back();
67 }
68 for (size_t fi = 0; fi < factor_list.size(); ++fi) {
69 if (static_cast<int>(factor_list.size()) >= null_dim) break;
70 if (factor_list[fi].size() <= 2) continue;
71 bk_split_one_factor(factor_list, fi, v_poly, null_dim, p);
72 }
73 }
74 return factor_list;
75}
static bool bk_split_one_factor(std::vector< std::vector< int64_t > > &factor_list, size_t fi, const std::vector< int64_t > &v_poly, int null_dim, int64_t p)

引用了 bk_split_factors() , 以及 bk_split_one_factor().

被这些函数引用 LMCAS::berlekamp_factor() , 以及 bk_split_factors().

函数调用图:
这是这个函数的调用关系图:

◆ bk_split_one_factor()

bool LMCAS::berlekamp_detail::bk_split_one_factor ( std::vector< std::vector< int64_t > > & factor_list,
size_t fi,
const std::vector< int64_t > & v_poly,
int null_dim,
int64_t p )
static

在文件 berlekamp_split.cpp 第 7 行定义.

9 {
10 for (int64_t c = 0; c < p; ++c) {
11 if (static_cast<int>(factor_list.size()) >= null_dim) return false;
12 std::vector<int64_t> v_minus_c = v_poly;
13 if (v_minus_c.empty()) {
14 v_minus_c.push_back((p - c) % p);
15 } else {
16 v_minus_c[0] = (v_minus_c[0] - c % p + p) % p;
17 }
18 while (!v_minus_c.empty() && v_minus_c.back() == 0) {
19 v_minus_c.pop_back();
20 }
21
22 if (v_minus_c.empty()) continue;
23 std::vector<int64_t> h = bk_gcd_mod(factor_list[fi], v_minus_c, p);
24 int deg_h = static_cast<int>(h.size()) - 1;
25 int deg_g = static_cast<int>(factor_list[fi].size()) - 1;
26
27 if (deg_h > 0 && deg_h < deg_g) {
28 std::vector<int64_t> quotient, remainder;
29 bk_div_mod(factor_list[fi], h, p, quotient, remainder);
30
31 factor_list[fi] = h;
32 factor_list.push_back(quotient);
33
34 return true;
35 }
36 }
37 return false;
38}

引用了 bk_div_mod(), bk_gcd_mod(), bk_split_one_factor() , 以及 LMCAS::c.

被这些函数引用 bk_split_factors() , 以及 bk_split_one_factor().

函数调用图:
这是这个函数的调用关系图:

变量说明

◆ BK_NUM_SMALL_PRIMES

size_t LMCAS::berlekamp_detail::BK_NUM_SMALL_PRIMES
staticconstexpr
初始值:
=
sizeof(BK_SMALL_PRIMES) / sizeof(BK_SMALL_PRIMES[0])

在文件 berlekamp_modular.cpp 第 19 行定义.

被这些函数引用 bk_select_prime().

◆ BK_SMALL_PRIMES

int64_t LMCAS::berlekamp_detail::BK_SMALL_PRIMES[]
staticconstexpr
初始值:
= {
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229
}

Berlekamp 模分解的小素数候选表。 按升序选取首个不整除首项系数且使模约化结果无平方因子的素数。

在文件 berlekamp_modular.cpp 第 12 行定义.

被这些函数引用 bk_select_prime().