Skip to content

Commit 3989b50

Browse files
committed
Merge remote-tracking branch 'origin/master' into fmpz_mod_mpoly_and_nmod_mpoly
2 parents 84fbf91 + f5b07e9 commit 3989b50

File tree

24 files changed

+2302
-102
lines changed

24 files changed

+2302
-102
lines changed

.github/workflows/buildwheel.yml

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
if: ${{ matrix.os == 'windows-2019' }}
4343

4444
- name: Build wheels
45-
uses: pypa/[email protected].1
45+
uses: pypa/[email protected].2
4646
env:
4747
# override setting in pyproject.toml to use msys2 instead of msys64 bash
4848
CIBW_BEFORE_ALL_WINDOWS: msys2 -c bin/cibw_before_all_windows.sh
@@ -138,6 +138,43 @@ jobs:
138138
- run: pip install .
139139
- run: python -m flint.test --verbose
140140

141+
# Test that we can still make a coverage build with setuptools.
142+
test_coverage_setuptools:
143+
name: Test coverage setuptools build
144+
runs-on: ubuntu-24.04
145+
steps:
146+
- uses: actions/checkout@v4
147+
- uses: actions/setup-python@v5
148+
with:
149+
python-version: '3.12'
150+
- run: sudo apt-get update
151+
- run: sudo apt-get install libflint-dev
152+
- run: pip install cython setuptools coverage
153+
- run: bin/coverage.sh
154+
env:
155+
PYTHONPATH: src
156+
- run: coverage report --sort=cover
157+
158+
# Run SymPy test suite against python-flint master
159+
test_sympy:
160+
name: Test SymPy ${{ matrix.sympy-version }}
161+
runs-on: ubuntu-24.04
162+
strategy:
163+
fail-fast: false
164+
matrix:
165+
sympy-version: ['1.13.1']
166+
steps:
167+
- uses: actions/checkout@v4
168+
- uses: actions/setup-python@v5
169+
with:
170+
python-version: '3.12'
171+
- run: sudo apt-get update
172+
- run: sudo apt-get install libflint-dev
173+
- run: pip install .
174+
- run: pip install pytest pytest-xdist hypothesis
175+
- run: pip install sympy==${{ matrix.sympy-version }}
176+
- run: python -c 'import sympy; sympy.test(parallel=True)'
177+
141178
# For older Ubuntu we have to build Flint >= 3.0.0
142179
test_flint_versions:
143180
name: Test flint ${{ matrix.flint-tag }}

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ CHANGELOG
133133

134134
Next release:
135135

136+
- [gh-172](https://github.com/flintlib/python-flint/pull/161)
137+
Add `fmpz_is_square`.
136138
- [gh-161](https://github.com/flintlib/python-flint/pull/161)
137139
Add `acb.lerch_phi` to compute the Lerch transcendent.
138140
- [gh-132](https://github.com/flintlib/python-flint/pull/132)
@@ -146,7 +148,7 @@ Next release:
146148
- [gh-148](https://github.com/flintlib/python-flint/pull/148)
147149
Remove debug symbols to make smaller Linux binaries.
148150
- [gh-144](https://github.com/flintlib/python-flint/pull/144)
149-
Add `rel_one_ccuracy_bits` to `arb` and `acb`.
151+
Add `rel_one_accuracy_bits` to `arb` and `acb`.
150152
- [gh-142](https://github.com/flintlib/python-flint/pull/142)
151153
Add `acb_theta` module for the numerical evaluation of [theta
152154
functions](https://flintlib.org/doc/acb_theta.html) (only available for

doc/source/fq_default.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
**fq_default** -- finite fields
2+
===============================================================================
3+
4+
.. autoclass :: flint.fq_default
5+
:members:
6+
:inherited-members:
7+
:undoc-members:
8+

doc/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Scalar types
4545
fmpq.rst
4646
fmpz_mod.rst
4747
nmod.rst
48+
fq_default.rst
4849
arb.rst
4950
acb.rst
5051
dirichlet.rst

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@
103103
("flint.types.fmpz_mod_mat", ["src/flint/types/fmpz_mod_mat.pyx"]),
104104

105105
("flint.types.fmpq_mpoly", ["src/flint/types/fmpq_mpoly.pyx"]),
106-
("flint.types.fmpz_mpoly_q", ["src/flint/types/fmpz_mpoly_q.pyx"]),
106+
107+
("flint.types.fq_default", ["src/flint/types/fq_default.pyx"]),
107108

108109
("flint.types.arf", ["src/flint/types/arf.pyx"]),
109110
("flint.types.arb", ["src/flint/types/arb.pyx"]),

src/flint/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
from .types.fmpq_mpoly import fmpq_mpoly_ctx, fmpq_mpoly, fmpq_mpoly_vec
2828

29+
from .types.fq_default import *
30+
2931
from .types.arf import *
3032
from .types.arb import *
3133
from .types.arb_poly import *

src/flint/flint_base/flint_base.pyx

Lines changed: 136 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,136 @@ cdef class flint_elem:
3030

3131

3232
cdef class flint_scalar(flint_elem):
33-
pass
33+
# =================================================
34+
# These are the functions a new class should define
35+
# assumes that addition and multiplication are
36+
# commutative
37+
# =================================================
38+
def is_zero(self):
39+
return False
40+
41+
def _any_as_self(self):
42+
return NotImplemented
43+
44+
def _neg_(self):
45+
return NotImplemented
46+
47+
def _add_(self, other):
48+
return NotImplemented
49+
50+
def _sub_(self, other):
51+
return NotImplemented
52+
53+
def _rsub_(self, other):
54+
return NotImplemented
55+
56+
def _mul_(self, other):
57+
return NotImplemented
58+
59+
def _div_(self, other):
60+
return NotImplemented
61+
62+
def _rdiv_(self, other):
63+
return NotImplemented
64+
65+
def _floordiv_(self, other):
66+
return NotImplemented
67+
68+
def _rfloordiv_(self, other):
69+
return NotImplemented
70+
71+
def _invert_(self):
72+
return NotImplemented
73+
74+
# =================================================
75+
# Generic arithmetic using the above functions
76+
# =================================================
77+
78+
def __pos__(self):
79+
return self
80+
81+
def __neg__(self):
82+
return self._neg_()
83+
84+
def __add__(self, other):
85+
other = self._any_as_self(other)
86+
if other is NotImplemented:
87+
return NotImplemented
88+
return self._add_(other)
89+
90+
def __radd__(self, other):
91+
other = self._any_as_self(other)
92+
if other is NotImplemented:
93+
return NotImplemented
94+
return self._add_(other)
95+
96+
def __sub__(self, other):
97+
other = self._any_as_self(other)
98+
if other is NotImplemented:
99+
return NotImplemented
100+
return self._sub_(other)
101+
102+
def __rsub__(self, other):
103+
other = self._any_as_self(other)
104+
if other is NotImplemented:
105+
return NotImplemented
106+
return self._rsub_(other)
107+
108+
def __mul__(self, other):
109+
other = self._any_as_self(other)
110+
if other is NotImplemented:
111+
return NotImplemented
112+
return self._mul_(other)
113+
114+
def __rmul__(self, other):
115+
other = self._any_as_self(other)
116+
if other is NotImplemented:
117+
return NotImplemented
118+
return self._mul_(other)
119+
120+
def __truediv__(self, other):
121+
other = self._any_as_self(other)
122+
if other is NotImplemented:
123+
return NotImplemented
124+
125+
if other.is_zero():
126+
raise ZeroDivisionError
127+
128+
return self._div_(other)
129+
130+
def __rtruediv__(self, other):
131+
if self.is_zero():
132+
raise ZeroDivisionError
133+
134+
other = self._any_as_self(other)
135+
if other is NotImplemented:
136+
return NotImplemented
137+
return self._rdiv_(other)
138+
139+
def __floordiv__(self, other):
140+
other = self._any_as_self(other)
141+
if other is NotImplemented:
142+
return NotImplemented
143+
144+
if other.is_zero():
145+
raise ZeroDivisionError
146+
147+
return self._floordiv_(other)
148+
149+
def __rfloordiv__(self, other):
150+
if self.is_zero():
151+
raise ZeroDivisionError
152+
153+
other = self._any_as_self(other)
154+
if other is NotImplemented:
155+
return NotImplemented
156+
return self._rfloordiv_(other)
157+
158+
def __invert__(self):
159+
if self.is_zero():
160+
raise ZeroDivisionError
161+
return self._invert_()
162+
34163

35164

36165
cdef class flint_poly(flint_elem):
@@ -55,7 +184,7 @@ cdef class flint_poly(flint_elem):
55184
"""
56185
return list(self)
57186

58-
def str(self, bint ascending=False, *args, **kwargs):
187+
def str(self, bint ascending=False, var="x", *args, **kwargs):
59188
"""
60189
Convert to a human-readable string (generic implementation for
61190
all polynomial types).
@@ -80,20 +209,20 @@ cdef class flint_poly(flint_elem):
80209
s.append("%s" % c)
81210
elif i == 1:
82211
if c == "1":
83-
s.append("x")
212+
s.append(var)
84213
else:
85-
s.append("%s*x" % c)
214+
s.append(f"{c}*{var}")
86215
else:
87216
if c == "1":
88-
s.append("x^%s" % i)
217+
s.append(f"{var}^{i}")
89218
else:
90-
s.append("%s*x^%s" % (c, i))
219+
s.append(f"{c}*{var}^{i}")
91220
return " + ".join(s)
92221

93222
def roots(self):
94223
"""
95224
Computes all the roots in the base ring of the polynomial.
96-
Returns a list of all pairs (*v*, *m*) where *v* is the
225+
Returns a list of all pairs (*v*, *m*) where *v* is the
97226
integer root and *m* is the multiplicity of the root.
98227
99228
To compute complex roots of a polynomial, instead use

src/flint/flintlib/fq.pxd

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
from flint.flintlib.flint cimport flint_bitcnt_t, fmpz_struct, slong, flint_rand_t, ulong
2+
from flint.flintlib.fmpz cimport fmpz_t, fmpz_struct
3+
from flint.flintlib.fmpz_mod cimport fmpz_mod_ctx_t
4+
from flint.flintlib.fmpz_mod_mat cimport fmpz_mod_mat_t
5+
from flint.flintlib.fmpz_poly cimport fmpz_poly_t, fmpz_poly_struct
6+
from flint.flintlib.fmpz_mod_poly cimport fmpz_mod_poly_t, fmpz_mod_poly_struct
7+
8+
cdef extern from "flint/fq.h":
9+
10+
ctypedef fmpz_poly_t fq_t
11+
ctypedef fmpz_poly_struct fq_struct
12+
13+
ctypedef struct fq_ctx_struct:
14+
fmpz_mod_ctx_t ctxp
15+
16+
int sparse_modulus
17+
int is_conway # whether field was initialized with the Flint Conway tables (assures primitivity)
18+
19+
fmpz_struct * a
20+
slong * j
21+
slong len
22+
23+
fmpz_mod_poly_t modulus
24+
fmpz_mod_poly_t inv
25+
26+
char * var
27+
28+
ctypedef fq_ctx_struct fq_ctx_t[1]
29+
30+
void fq_ctx_init(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var)
31+
int _fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var)
32+
void fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var)
33+
void fq_ctx_init_modulus(fq_ctx_t ctx, const fmpz_mod_poly_t modulus, const fmpz_mod_ctx_t ctxp, const char *var)
34+
void fq_ctx_clear(fq_ctx_t ctx)
35+
const fmpz_mod_poly_struct* fq_ctx_modulus(const fq_ctx_t ctx)
36+
long fq_ctx_degree(const fq_ctx_t ctx)
37+
fmpz_struct * fq_ctx_prime(const fq_ctx_t ctx)
38+
void fq_ctx_order(fmpz_t f, const fq_ctx_t ctx)
39+
# int fq_ctx_fprint(FILE * file, const fq_ctx_t ctx)
40+
void fq_ctx_print(const fq_ctx_t ctx)
41+
void fq_ctx_randtest(fq_ctx_t ctx)
42+
void fq_ctx_randtest_reducible(fq_ctx_t ctx)
43+
void fq_init(fq_t rop, const fq_ctx_t ctx)
44+
void fq_init2(fq_t rop, const fq_ctx_t ctx)
45+
void fq_clear(fq_t rop, const fq_ctx_t ctx)
46+
void _fq_sparse_reduce(fmpz_struct *R, slong lenR, const fq_ctx_t ctx)
47+
void _fq_dense_reduce(fmpz_struct *R, slong lenR, const fq_ctx_t ctx)
48+
void _fq_reduce(fmpz_struct *r, slong lenR, const fq_ctx_t ctx)
49+
void fq_reduce(fq_t rop, const fq_ctx_t ctx)
50+
void fq_add(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx)
51+
void fq_sub(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx)
52+
void fq_sub_one(fq_t rop, const fq_t op1, const fq_ctx_t ctx)
53+
void fq_neg(fq_t rop, const fq_t op, const fq_ctx_t ctx)
54+
void fq_mul(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx)
55+
void fq_mul_fmpz(fq_t rop, const fq_t op, const fmpz_t x, const fq_ctx_t ctx)
56+
void fq_mul_si(fq_t rop, const fq_t op, slong x, const fq_ctx_t ctx)
57+
void fq_mul_ui(fq_t rop, const fq_t op, ulong x, const fq_ctx_t ctx)
58+
void fq_sqr(fq_t rop, const fq_t op, const fq_ctx_t ctx)
59+
void fq_div(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx)
60+
void _fq_inv(fmpz_struct *rop, const fmpz_struct *op, slong len, const fq_ctx_t ctx)
61+
void fq_inv(fq_t rop, const fq_t op, const fq_ctx_t ctx)
62+
void fq_gcdinv(fq_t f, fq_t inv, const fq_t op, const fq_ctx_t ctx)
63+
void _fq_pow(fmpz_struct *rop, const fmpz_struct *op, slong len, const fmpz_t e, const fq_ctx_t ctx)
64+
void fq_pow(fq_t rop, const fq_t op, const fmpz_t e, const fq_ctx_t ctx)
65+
void fq_pow_ui(fq_t rop, const fq_t op, const ulong e, const fq_ctx_t ctx)
66+
int fq_sqrt(fq_t rop, const fq_t op1, const fq_ctx_t ctx)
67+
void fq_pth_root(fq_t rop, const fq_t op1, const fq_ctx_t ctx)
68+
int fq_is_square(const fq_t op, const fq_ctx_t ctx)
69+
# int fq_fprint_pretty(FILE *file, const fq_t op, const fq_ctx_t ctx)
70+
int fq_print_pretty(const fq_t op, const fq_ctx_t ctx)
71+
# void fq_fprint(FILE * file, const fq_t op, const fq_ctx_t ctx)
72+
void fq_print(const fq_t op, const fq_ctx_t ctx)
73+
char * fq_get_str(const fq_t op, const fq_ctx_t ctx)
74+
char * fq_get_str_pretty(const fq_t op, const fq_ctx_t ctx)
75+
void fq_randtest(fq_t rop, flint_rand_t state, const fq_ctx_t ctx)
76+
void fq_randtest_not_zero(fq_t rop, flint_rand_t state, const fq_ctx_t ctx)
77+
void fq_randtest_dense(fq_t rop, flint_rand_t state, const fq_ctx_t ctx)
78+
void fq_rand(fq_t rop, flint_rand_t state, const fq_ctx_t ctx)
79+
void fq_rand_not_zero(fq_t rop, flint_rand_t state, const fq_ctx_t ctx)
80+
void fq_set(fq_t rop, const fq_t op, const fq_ctx_t ctx)
81+
void fq_set_si(fq_t rop, const slong x, const fq_ctx_t ctx)
82+
void fq_set_ui(fq_t rop, const ulong x, const fq_ctx_t ctx)
83+
void fq_set_fmpz(fq_t rop, const fmpz_t x, const fq_ctx_t ctx)
84+
void fq_swap(fq_t op1, fq_t op2, const fq_ctx_t ctx)
85+
void fq_zero(fq_t rop, const fq_ctx_t ctx)
86+
void fq_one(fq_t rop, const fq_ctx_t ctx)
87+
void fq_gen(fq_t rop, const fq_ctx_t ctx)
88+
int fq_get_fmpz(fmpz_t rop, const fq_t op, const fq_ctx_t ctx)
89+
void fq_get_fmpz_poly(fmpz_poly_t a, const fq_t b, const fq_ctx_t ctx)
90+
void fq_get_fmpz_mod_poly(fmpz_mod_poly_t a, const fq_t b, const fq_ctx_t ctx)
91+
void fq_set_fmpz_poly(fq_t a, const fmpz_poly_t b, const fq_ctx_t ctx)
92+
void fq_set_fmpz_mod_poly(fq_t a, const fmpz_mod_poly_t b, const fq_ctx_t ctx)
93+
void fq_get_fmpz_mod_mat(fmpz_mod_mat_t col, const fq_t a, const fq_ctx_t ctx)
94+
void fq_set_fmpz_mod_mat(fq_t a, const fmpz_mod_mat_t col, const fq_ctx_t ctx)
95+
int fq_is_zero(const fq_t op, const fq_ctx_t ctx)
96+
int fq_is_one(const fq_t op, const fq_ctx_t ctx)
97+
int fq_equal(const fq_t op1, const fq_t op2, const fq_ctx_t ctx)
98+
int fq_is_invertible(const fq_t op, const fq_ctx_t ctx)
99+
int fq_is_invertible_f(fq_t f, const fq_t op, const fq_ctx_t ctx)
100+
void _fq_trace(fmpz_t rop, const fmpz_struct *op, slong len, const fq_ctx_t ctx)
101+
void fq_trace(fmpz_t rop, const fq_t op, const fq_ctx_t ctx)
102+
void _fq_norm(fmpz_t rop, const fmpz_struct *op, slong len, const fq_ctx_t ctx)
103+
void fq_norm(fmpz_t rop, const fq_t op, const fq_ctx_t ctx)
104+
void _fq_frobenius(fmpz_struct *rop, const fmpz_struct *op, slong len, slong e, const fq_ctx_t ctx)
105+
void fq_frobenius(fq_t rop, const fq_t op, slong e, const fq_ctx_t ctx)
106+
int fq_multiplicative_order(fmpz_t ord, const fq_t op, const fq_ctx_t ctx)
107+
int fq_is_primitive(const fq_t op, const fq_ctx_t ctx)
108+
void fq_bit_pack(fmpz_t f, const fq_t op, flint_bitcnt_t bit_size, const fq_ctx_t ctx)
109+
void fq_bit_unpack(fq_t rop, const fmpz_t f, flint_bitcnt_t bit_size, const fq_ctx_t ctx)

0 commit comments

Comments
 (0)