LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
berlekamp_split.cpp
浏览该文件的文档.
2#include <algorithm>
3#include <limits>
4
6
7static bool bk_split_one_factor(std::vector<std::vector<int64_t>>& factor_list,
8 size_t fi, const std::vector<int64_t>& v_poly,
9 int null_dim, int64_t p) {
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}
39
40std::vector<std::vector<int64_t>> bk_split_factors(
41 const std::vector<int64_t>& f_coeffs,
42 const std::vector<std::vector<int64_t>>& null_basis,
43 int null_dim,
44 int64_t p) {
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}
76
77}
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)
std::vector< int64_t > bk_gcd_mod(std::vector< int64_t > a, std::vector< int64_t > b, 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 多项式带余除法.
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)
const VectorField const VectorField & c