passagemath-brial 10.8.1a3__cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_brial/__init__.py +3 -0
- passagemath_brial-10.8.1a3.dist-info/METADATA +96 -0
- passagemath_brial-10.8.1a3.dist-info/RECORD +39 -0
- passagemath_brial-10.8.1a3.dist-info/WHEEL +6 -0
- passagemath_brial-10.8.1a3.dist-info/top_level.txt +3 -0
- passagemath_brial.libs/libbrial-a2b87c7c.so.3.0.7 +0 -0
- passagemath_brial.libs/libbrial_groebner-607bf574.so.3.0.7 +0 -0
- passagemath_brial.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
- passagemath_brial.libs/libm4ri-4311ab86.so.2.0.1 +0 -0
- passagemath_brial.libs/libpng16-5d944a30.so.16.54.0 +0 -0
- sage/all__sagemath_brial.py +9 -0
- sage/libs/all__sagemath_brial.py +1 -0
- sage/libs/polybori/__init__.pxd +2 -0
- sage/libs/polybori/decl.pxd +401 -0
- sage/libs/polybori/pb_wrap.h +133 -0
- sage/rings/all__sagemath_brial.py +1 -0
- sage/rings/polynomial/all__sagemath_brial.py +1 -0
- sage/rings/polynomial/pbori/PyPolyBoRi.py +124 -0
- sage/rings/polynomial/pbori/__init__.py +46 -0
- sage/rings/polynomial/pbori/blocks.py +499 -0
- sage/rings/polynomial/pbori/cnf.py +241 -0
- sage/rings/polynomial/pbori/easy_polynomials.py +59 -0
- sage/rings/polynomial/pbori/fglm.py +93 -0
- sage/rings/polynomial/pbori/frontend.py +70 -0
- sage/rings/polynomial/pbori/gbcore.py +644 -0
- sage/rings/polynomial/pbori/gbrefs.py +129 -0
- sage/rings/polynomial/pbori/heuristics.py +35 -0
- sage/rings/polynomial/pbori/interpolate.py +122 -0
- sage/rings/polynomial/pbori/interred.py +34 -0
- sage/rings/polynomial/pbori/ll.py +302 -0
- sage/rings/polynomial/pbori/nf.py +671 -0
- sage/rings/polynomial/pbori/parallel.py +308 -0
- sage/rings/polynomial/pbori/pbori.cpython-314-aarch64-linux-gnu.so +0 -0
- sage/rings/polynomial/pbori/pbori.pxd +127 -0
- sage/rings/polynomial/pbori/pbori.pyx +8103 -0
- sage/rings/polynomial/pbori/randompoly.py +111 -0
- sage/rings/polynomial/pbori/rank.py +27 -0
- sage/rings/polynomial/pbori/specialsets.py +119 -0
- sage/rings/polynomial/pbori/statistics.py +35 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-brial
|
|
2
|
+
# sage.doctest: needs sage.rings.polynomial.pbori
|
|
3
|
+
from pprint import pformat
|
|
4
|
+
from random import Random
|
|
5
|
+
|
|
6
|
+
from sage.rings.polynomial.pbori.blocks import declare_ring
|
|
7
|
+
from sage.rings.polynomial.pbori.ll import ll_encode
|
|
8
|
+
from sage.rings.polynomial.pbori.pbori import (
|
|
9
|
+
Monomial,
|
|
10
|
+
Polynomial,
|
|
11
|
+
Variable,
|
|
12
|
+
ll_red_nf_redsb,
|
|
13
|
+
random_set,
|
|
14
|
+
set_random_seed,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def gen_random_poly(ring, l, deg, vars_set, seed=123):
|
|
19
|
+
"""
|
|
20
|
+
Generate a random polynomial with coefficients in ``ring``.
|
|
21
|
+
|
|
22
|
+
EXAMPLES::
|
|
23
|
+
|
|
24
|
+
sage: from sage.rings.polynomial.pbori.PyPolyBoRi import Ring, Variable
|
|
25
|
+
sage: from sage.rings.polynomial.pbori.randompoly import gen_random_poly
|
|
26
|
+
sage: r = Ring(16)
|
|
27
|
+
sage: vars = [Variable(i,r) for i in range(10)]
|
|
28
|
+
sage: gen_random_poly(r, 4, 10, vars) # random
|
|
29
|
+
x(0)*x(1)*x(2)*x(5)*x(8)*x(9) + x(0)*x(1)*x(4)*x(6) + x(0)*x(2)*x(3)*x(7)*x(9) + x(5)*x(8)
|
|
30
|
+
"""
|
|
31
|
+
myrange = vars_set
|
|
32
|
+
r = Random(seed)
|
|
33
|
+
|
|
34
|
+
def helper(samples):
|
|
35
|
+
if samples == 0:
|
|
36
|
+
return Polynomial(ring.zero())
|
|
37
|
+
if samples == 1:
|
|
38
|
+
d = r.randint(0, deg)
|
|
39
|
+
variables = r.sample(myrange, d)
|
|
40
|
+
m = Monomial(ring)
|
|
41
|
+
for v in sorted(set(variables), reverse=True):
|
|
42
|
+
m = m * Variable(v, ring)
|
|
43
|
+
return Polynomial(m)
|
|
44
|
+
assert samples >= 2
|
|
45
|
+
return helper(samples // 2) + helper(samples - samples // 2)
|
|
46
|
+
p = Polynomial(ring.zero())
|
|
47
|
+
while len(p) < l:
|
|
48
|
+
p = Polynomial(p.set().union(helper(l - len(p)).set()))
|
|
49
|
+
return p
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def sparse_random_system(ring, number_of_polynomials, variables_per_polynomial,
|
|
53
|
+
degree, random_seed=None):
|
|
54
|
+
r"""
|
|
55
|
+
Generate a sparse random system.
|
|
56
|
+
|
|
57
|
+
Generate a system, which is sparse in the sense, that each polynomial
|
|
58
|
+
contains only a small subset of variables. In each variable that occurs
|
|
59
|
+
in a polynomial it is dense in the terms up to the given degree
|
|
60
|
+
(every term occurs with probability 1/2).
|
|
61
|
+
|
|
62
|
+
The system will be satisfiable by at least one solution.
|
|
63
|
+
|
|
64
|
+
TESTS::
|
|
65
|
+
|
|
66
|
+
sage: from sage.rings.polynomial.pbori import Ring, groebner_basis
|
|
67
|
+
sage: r = Ring(10)
|
|
68
|
+
sage: from sage.rings.polynomial.pbori.randompoly import sparse_random_system
|
|
69
|
+
sage: s = sparse_random_system(r, number_of_polynomials=20, variables_per_polynomial=3, degree=2, random_seed=int(123))
|
|
70
|
+
sage: [p.deg() for p in s]
|
|
71
|
+
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
|
72
|
+
sage: sorted(groebner_basis(s), reverse=True)
|
|
73
|
+
[x(0), x(1) + 1, x(2), x(3) + 1, x(4) + 1, x(5), x(6), x(7) + 1, x(8) + 1, x(9) + 1]
|
|
74
|
+
"""
|
|
75
|
+
if random_seed is not None:
|
|
76
|
+
set_random_seed(random_seed)
|
|
77
|
+
random_generator = Random(random_seed)
|
|
78
|
+
variables = [ring.variable(i) for i in range(ring.n_variables())]
|
|
79
|
+
solutions = [v + random_generator.randint(0, 1) for v in variables]
|
|
80
|
+
solutions = ll_encode(solutions)
|
|
81
|
+
res = []
|
|
82
|
+
while len(res) < number_of_polynomials:
|
|
83
|
+
variables_as_monomial = Monomial(
|
|
84
|
+
random_generator.sample(
|
|
85
|
+
variables,
|
|
86
|
+
variables_per_polynomial)
|
|
87
|
+
)
|
|
88
|
+
p = Polynomial(random_set(variables_as_monomial, 2 ** (
|
|
89
|
+
variables_per_polynomial - 1)))
|
|
90
|
+
p = sum([p.graded_part(i) for i in range(degree + 1)])
|
|
91
|
+
if p.deg() == degree:
|
|
92
|
+
res.append(p)
|
|
93
|
+
# evaluate it to guarantee a solution
|
|
94
|
+
return [p + ll_red_nf_redsb(p, solutions) for p in res]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def sparse_random_system_data_file_content(number_of_variables, **kwds):
|
|
98
|
+
r"""
|
|
99
|
+
TESTS::
|
|
100
|
+
|
|
101
|
+
sage: from sage.rings.polynomial.pbori.randompoly import sparse_random_system_data_file_content
|
|
102
|
+
sage: sparse_random_system_data_file_content(10, number_of_polynomials=5, variables_per_polynomial=3, degree=2, random_seed=int(123))
|
|
103
|
+
"declare_ring(['x'+str(i) for in range(10)])\nideal=\\\n[...]\n\n"
|
|
104
|
+
"""
|
|
105
|
+
dummy_dict = {}
|
|
106
|
+
r = declare_ring(['x' + str(i) for i in range(number_of_variables)],
|
|
107
|
+
dummy_dict)
|
|
108
|
+
polynomials = sparse_random_system(r, **kwds)
|
|
109
|
+
polynomials = pformat(polynomials)
|
|
110
|
+
return "declare_ring(['x'+str(i) for in range({})])\nideal=\\\n{}\n\n".format(
|
|
111
|
+
number_of_variables, polynomials)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-brial
|
|
2
|
+
# sage.doctest: needs sage.rings.polynomial.pbori
|
|
3
|
+
def input_signals(p):
|
|
4
|
+
return list((p + p.lex_lead()).vars_as_monomial().variables())
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def output_signal(p):
|
|
8
|
+
return next(iter(p.lex_lead().variables()))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def rank(data):
|
|
12
|
+
parents = {}
|
|
13
|
+
res = {}
|
|
14
|
+
for p in data:
|
|
15
|
+
out = output_signal(p)
|
|
16
|
+
parents.setdefault(out, [])
|
|
17
|
+
for v in input_signals(p):
|
|
18
|
+
parents.setdefault(v, []).append(out)
|
|
19
|
+
|
|
20
|
+
def do_rank(v):
|
|
21
|
+
if v in res:
|
|
22
|
+
return res[v]
|
|
23
|
+
my_res = res[v] = max((do_rank(p) + 1 for p in parents[v]), default=0)
|
|
24
|
+
return my_res
|
|
25
|
+
for v in parents:
|
|
26
|
+
do_rank(v)
|
|
27
|
+
return res
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-brial
|
|
2
|
+
# sage.doctest: needs sage.rings.polynomial.pbori
|
|
3
|
+
from sage.rings.polynomial.pbori.pbori import (
|
|
4
|
+
BooleConstant,
|
|
5
|
+
BooleSet,
|
|
6
|
+
Monomial,
|
|
7
|
+
Polynomial,
|
|
8
|
+
Variable,
|
|
9
|
+
if_then_else,
|
|
10
|
+
mod_mon_set,
|
|
11
|
+
top_index,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def all_monomials_of_degree_d_old(d, variables):
|
|
16
|
+
"""
|
|
17
|
+
Return monomials of degree d in the given variables.
|
|
18
|
+
|
|
19
|
+
Obsolete version ?
|
|
20
|
+
"""
|
|
21
|
+
if d == 0:
|
|
22
|
+
return BooleConstant(1)
|
|
23
|
+
|
|
24
|
+
if not variables:
|
|
25
|
+
return []
|
|
26
|
+
variables = sorted(set(variables), reverse=True, key=top_index)
|
|
27
|
+
|
|
28
|
+
m = variables[-1]
|
|
29
|
+
for v in variables[:-1]:
|
|
30
|
+
m = v + m
|
|
31
|
+
m = m.set()
|
|
32
|
+
i = 0
|
|
33
|
+
res = Polynomial(variables[0].ring().one()).set()
|
|
34
|
+
while i < d:
|
|
35
|
+
i += 1
|
|
36
|
+
res = res.cartesian_product(m).diff(res)
|
|
37
|
+
return res
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def all_monomials_of_degree_d(d, variables):
|
|
41
|
+
"""
|
|
42
|
+
Return monomials of degree d in the given variables.
|
|
43
|
+
"""
|
|
44
|
+
variables = Monomial(variables)
|
|
45
|
+
variables = list(variables.variables())
|
|
46
|
+
if not variables:
|
|
47
|
+
assert d == 0
|
|
48
|
+
return BooleConstant(1)
|
|
49
|
+
ring = variables[0].ring()
|
|
50
|
+
if d > len(variables):
|
|
51
|
+
return Polynomial(0, ring)
|
|
52
|
+
if d < 0:
|
|
53
|
+
return Polynomial(1, ring)
|
|
54
|
+
|
|
55
|
+
deg_variables = variables[-d:]
|
|
56
|
+
# this ensures sorting by indices
|
|
57
|
+
res = Monomial(deg_variables)
|
|
58
|
+
|
|
59
|
+
for i in range(1, len(variables) - d + 1):
|
|
60
|
+
deg_variables = variables[-d - i:-i]
|
|
61
|
+
res = Polynomial(res)
|
|
62
|
+
nav = res.navigation()
|
|
63
|
+
navs = []
|
|
64
|
+
while not nav.constant():
|
|
65
|
+
navs.append(BooleSet(nav, ring))
|
|
66
|
+
nav = nav.then_branch()
|
|
67
|
+
acc = Polynomial(1, ring)
|
|
68
|
+
for (nav, v) in reversed(zip(navs, deg_variables)):
|
|
69
|
+
acc = if_then_else(v, acc, nav)
|
|
70
|
+
res = acc
|
|
71
|
+
return res.set()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def power_set(variables):
|
|
75
|
+
"""
|
|
76
|
+
Return all subsets of the given variables.
|
|
77
|
+
"""
|
|
78
|
+
if not variables:
|
|
79
|
+
return BooleConstant(1)
|
|
80
|
+
variables = sorted(set(variables), reverse=True, key=top_index)
|
|
81
|
+
res = Polynomial(1, variables[0].ring()).set()
|
|
82
|
+
for v in variables:
|
|
83
|
+
res = if_then_else(v, res, res)
|
|
84
|
+
return res
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
if __name__ == '__main__':
|
|
88
|
+
from .blocks import Block, declare_ring
|
|
89
|
+
r = declare_ring([Block("x", 10000)], globals())
|
|
90
|
+
print(list(all_monomials_of_degree_d(0, [Variable(i) for i in range(100)])))
|
|
91
|
+
print(list(all_monomials_of_degree_d(1, [Variable(i) for i in range(10)])))
|
|
92
|
+
print(list(all_monomials_of_degree_d(2, [Variable(i) for i in range(4)])))
|
|
93
|
+
print(list(all_monomials_of_degree_d(3, [Variable(i) for i in range(4)])))
|
|
94
|
+
print(list(all_monomials_of_degree_d(4, [Variable(i) for i in range(4)])))
|
|
95
|
+
print(list(all_monomials_of_degree_d(0, [])))
|
|
96
|
+
print(list(all_monomials_of_degree_d(1, [])))
|
|
97
|
+
print(list(power_set([Variable(i) for i in range(2)])))
|
|
98
|
+
print(list(power_set([Variable(i) for i in range(4)])))
|
|
99
|
+
print(list(power_set()))
|
|
100
|
+
# every monomial in the first 8 var, which is at most linear in the first 5
|
|
101
|
+
print(list(mod_mon_set(
|
|
102
|
+
power_set([Variable(i) for i in range(8)]),
|
|
103
|
+
all_monomials_of_degree_d(2, [Variable(i) for i in range(5)]))))
|
|
104
|
+
|
|
105
|
+
# specialized normal form computation
|
|
106
|
+
print(Polynomial(
|
|
107
|
+
mod_mon_set(
|
|
108
|
+
(x(1) * x(2) + x(1) + 1).set(),
|
|
109
|
+
all_monomials_of_degree_d(2, [Variable(i) for i in range(1000)]))))
|
|
110
|
+
print(list(mod_mon_set(
|
|
111
|
+
power_set([Variable(i) for i in range(50)]),
|
|
112
|
+
all_monomials_of_degree_d(2, [Variable(i) for i in range(1000)]))))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def monomial_from_indices(ring, indices):
|
|
116
|
+
res = Monomial(ring)
|
|
117
|
+
for i in sorted(indices, reverse=True):
|
|
118
|
+
res = res * ring.variable(i)
|
|
119
|
+
return res
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-brial
|
|
2
|
+
# sage.doctest: needs sage.rings.polynomial.pbori
|
|
3
|
+
from sage.rings.polynomial.pbori.pbori import (
|
|
4
|
+
BooleConstant,
|
|
5
|
+
Monomial,
|
|
6
|
+
Polynomial,
|
|
7
|
+
top_index,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def used_vars(l, bound=None):
|
|
12
|
+
if not l:
|
|
13
|
+
return BooleConstant(1)
|
|
14
|
+
m = Monomial(Polynomial(next(iter(l))).vars_as_monomial())
|
|
15
|
+
for p in l[1:]:
|
|
16
|
+
m = m * Polynomial(p).vars_as_monomial()
|
|
17
|
+
if bound and len(m) > bound:
|
|
18
|
+
return m
|
|
19
|
+
return m
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def used_vars_set(l, bound=None):
|
|
23
|
+
if not l:
|
|
24
|
+
return BooleConstant(1)
|
|
25
|
+
s = set()
|
|
26
|
+
for p in l:
|
|
27
|
+
s.update(Polynomial(p).vars_as_monomial().variables())
|
|
28
|
+
if bound and len(s) > bound:
|
|
29
|
+
break
|
|
30
|
+
sorted_s = sorted(s, key=top_index, reverse=True)
|
|
31
|
+
m = Monomial(next(iter(l)).ring())
|
|
32
|
+
for v in sorted_s:
|
|
33
|
+
m = v * m
|
|
34
|
+
|
|
35
|
+
return m
|