Skip to content

Commit 0320eab

Browse files
Merge branch 'main' into intconv
2 parents 78e85af + e6033bf commit 0320eab

File tree

7 files changed

+154
-10
lines changed

7 files changed

+154
-10
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ Changes (0.9.0):
194194
work. (OB)
195195
- [gh-324](https://github.com/flintlib/python-flint/pull/324),
196196
Faster conversion from `int` to `fmpz` and back. (RO).
197+
- [gh-359](https://github.com/flintlib/python-flint/pull/359),
198+
Sort factorisations of all mpoly types. (OB)
197199

198200
0.8.0
199201
-----

src/flint/test/test_all.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4052,7 +4052,7 @@ def factor_sqf(p):
40524052
# *_mpoly types
40534053

40544054
assert factor(x*y+1) == (S(1), [(x*y+1, 1)])
4055-
assert factor(x*y) == (S(1), [(x, 1), (y, 1)])
4055+
assert factor(x*y) == (S(1), [(y, 1), (x, 1)])
40564056

40574057
assert factor_sqf((x*y+1)**2*(x*y-1)) == (S(1), [(x*y-1, 1), (x*y+1, 2)])
40584058

@@ -5059,7 +5059,7 @@ def test_fq_default_poly():
50595059
break
50605060
while True:
50615061
h = R_test.random_element()
5062-
if f.gcd(h).is_one():
5062+
if f.gcd(h).is_one() and h.degree() >= 1:
50635063
break
50645064
g = f.inverse_mod(h)
50655065
assert f.mul_mod(g, h).is_one()

src/flint/types/acb_theta.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def acb_theta(acb_mat z, acb_mat tau, ulong square=False):
3030
[ 1.030556961196006476576271 + 0.03055696120816803328582847j]
3131
[ -1.220790267576967690128359 - 1.827055516791154669091679j]
3232
[ -1.820235910124989594900076 + 1.216251950154477951760042j]
33-
>>> acb_mat([[1j,0],[0,2*1j]]).theta(acb_mat([[0],[0]])).transpose()
33+
>>> acb_mat([[1j,0],[0,2*1j]]).theta(acb_mat([[0],[0]])).transpose() # doctest: +SKIP
3434
[ [1.09049252082308 +/- 5.07e-15] + [+/- 1.73e-15]j]
3535
[ [1.08237710165638 +/- 5.64e-15] + [+/- 1.74e-15]j]
3636
[ [0.91699125162112 +/- 4.17e-15] + [+/- 1.33e-15]j]
@@ -48,7 +48,7 @@ def acb_theta(acb_mat z, acb_mat tau, ulong square=False):
4848
[ [+/- 2.60e-17] + [+/- 2.60e-17]j]
4949
[ [+/- 1.16e-16] + [+/- 1.16e-16]j]
5050
>>> ctx.prec = 10000
51-
>>> print(acb_mat([[1j, 0],[0,1j]]).theta(acb_mat([[0],[0]])).transpose().str(25))
51+
>>> print(acb_mat([[1j, 0],[0,1j]]).theta(acb_mat([[0],[0]])).transpose().str(25)) # doctest: +SKIP
5252
[ [1.180340599016096226045338 +/- 5.95e-26] + [+/- 2.35e-3010]j]
5353
[[0.9925441784910574194770081 +/- 3.15e-26] + [+/- 2.79e-3010]j]
5454
[[0.9925441784910574194770081 +/- 3.15e-26] + [+/- 1.88e-3010]j]

src/flint/types/fmpq_mpoly.pyx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
cimport cython
2+
3+
from flint.flintlib.types.flint cimport ulong
4+
15
from flint.flint_base.flint_base cimport (
26
flint_mpoly,
37
flint_mpoly_context,
@@ -856,9 +860,9 @@ cdef class fmpq_mpoly(flint_mpoly):
856860
>>> p1 = Zm("2*x + 4", ctx)
857861
>>> p2 = Zm("3*x*z + 3*x + 3*z + 3", ctx)
858862
>>> (p1 * p2).factor()
859-
(6, [(z + 1, 1), (x + 2, 1), (x + 1, 1)])
863+
(6, [(z + 1, 1), (x + 1, 1), (x + 2, 1)])
860864
>>> (p2 * p1 * p2).factor()
861-
(18, [(z + 1, 2), (x + 2, 1), (x + 1, 2)])
865+
(18, [(x + 2, 1), (z + 1, 2), (x + 1, 2)])
862866
"""
863867
cdef:
864868
fmpq_mpoly_factor_t fac
@@ -881,6 +885,9 @@ cdef class fmpq_mpoly(flint_mpoly):
881885
c = fmpq.__new__(fmpq)
882886
fmpq_set((<fmpq>c).val, fac.constant)
883887
fmpq_mpoly_factor_clear(fac, self.ctx.val)
888+
889+
res.sort(key=_fmpq_mpoly_sort_key)
890+
884891
return c, res
885892

886893
def factor_squarefree(self):
@@ -1126,6 +1133,35 @@ cdef class fmpq_mpoly(flint_mpoly):
11261133
return res
11271134

11281135

1136+
@cython.final
1137+
@cython.no_gc
1138+
cdef class _fmpq_mpoly_sort_key:
1139+
cdef fmpq_mpoly p
1140+
cdef ulong mult
1141+
1142+
def __init__(self, tuple fac_m):
1143+
self.p = fac_m[0]
1144+
self.mult = fac_m[1]
1145+
1146+
def __lt__(k1, _fmpq_mpoly_sort_key k2):
1147+
cdef slong nterms
1148+
cdef tuple monom1, monom2
1149+
cdef fmpq coeff1, coeff2
1150+
if k1.mult != k2.mult:
1151+
return k1.mult < k2.mult
1152+
nterms = min(len(k1.p), len(k2.p))
1153+
for i in range(nterms):
1154+
monom1 = k1.p.monomial(i)
1155+
monom2 = k2.p.monomial(i)
1156+
if monom1 != monom2:
1157+
return monom1 < monom2
1158+
coeff1 = k1.p.coefficient(i)
1159+
coeff2 = k2.p.coefficient(i)
1160+
if coeff1 != coeff2:
1161+
return coeff1 < coeff2
1162+
return len(k1.p) < len(k2.p)
1163+
1164+
11291165
cdef class fmpq_mpoly_vec:
11301166
"""
11311167
A class representing a vector of fmpq_mpolys. Not present in FLINT.

src/flint/types/fmpz_mod_mpoly.pyx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
cimport cython
2+
3+
from flint.flintlib.types.flint cimport ulong
4+
15
from flint.flint_base.flint_base cimport (
26
flint_mpoly,
37
flint_mod_mpoly_context,
@@ -871,7 +875,7 @@ cdef class fmpz_mod_mpoly(flint_mpoly):
871875
>>> (p1 * p2).factor()
872876
(6, [(z + 1, 1), (x + 1, 1), (x + 2, 1)])
873877
>>> (p2 * p1 * p2).factor()
874-
(7, [(z + 1, 2), (x + 2, 1), (x + 1, 2)])
878+
(7, [(x + 2, 1), (z + 1, 2), (x + 1, 2)])
875879
"""
876880
cdef:
877881
fmpz_mod_mpoly_factor_t fac
@@ -898,6 +902,9 @@ cdef class fmpz_mod_mpoly(flint_mpoly):
898902
c = fmpz.__new__(fmpz)
899903
fmpz_set((<fmpz>c).val, fac.constant)
900904
fmpz_mod_mpoly_factor_clear(fac, self.ctx.val)
905+
906+
res.sort(key=_fmpz_mod_mpoly_sort_key)
907+
901908
return c, res
902909

903910
def factor_squarefree(self):
@@ -1132,6 +1139,35 @@ cdef class fmpz_mod_mpoly(flint_mpoly):
11321139
return ctx.from_dict(res1.to_dict())
11331140

11341141

1142+
@cython.final
1143+
@cython.no_gc
1144+
cdef class _fmpz_mod_mpoly_sort_key:
1145+
cdef fmpz_mod_mpoly p
1146+
cdef ulong mult
1147+
1148+
def __init__(self, tuple fac_m):
1149+
self.p = fac_m[0]
1150+
self.mult = fac_m[1]
1151+
1152+
def __lt__(k1, _fmpz_mod_mpoly_sort_key k2):
1153+
cdef slong nterms
1154+
cdef tuple monom1, monom2
1155+
cdef int coeff1, coeff2
1156+
if k1.mult != k2.mult:
1157+
return k1.mult < k2.mult
1158+
nterms = min(k1.p.val.length, k2.p.val.length)
1159+
for i in range(nterms):
1160+
monom1 = k1.p.monomial(i)
1161+
monom2 = k2.p.monomial(i)
1162+
if monom1 != monom2:
1163+
return monom1 < monom2
1164+
coeff1 = int(k1.p.coefficient(i))
1165+
coeff2 = int(k2.p.coefficient(i))
1166+
if coeff1 != coeff2:
1167+
return coeff1 < coeff2
1168+
return k1.p.val.length < k2.p.val.length
1169+
1170+
11351171
cdef class fmpz_mod_mpoly_vec:
11361172
"""
11371173
A class representing a vector of fmpz_mod_mpolys.

src/flint/types/fmpz_mpoly.pyx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
cimport cython
2+
3+
from flint.flintlib.types.flint cimport ulong
4+
15
from flint.flint_base.flint_base cimport (
26
flint_mpoly,
37
flint_mpoly_context,
@@ -874,9 +878,9 @@ cdef class fmpz_mpoly(flint_mpoly):
874878
>>> p1 = Zm("2*x + 4", ctx)
875879
>>> p2 = Zm("3*x*z + 3*x + 3*z + 3", ctx)
876880
>>> (p1 * p2).factor()
877-
(6, [(z + 1, 1), (x + 2, 1), (x + 1, 1)])
881+
(6, [(z + 1, 1), (x + 1, 1), (x + 2, 1)])
878882
>>> (p2 * p1 * p2).factor()
879-
(18, [(z + 1, 2), (x + 2, 1), (x + 1, 2)])
883+
(18, [(x + 2, 1), (z + 1, 2), (x + 1, 2)])
880884
"""
881885
cdef:
882886
fmpz_mpoly_factor_t fac
@@ -900,6 +904,9 @@ cdef class fmpz_mpoly(flint_mpoly):
900904
c = fmpz.__new__(fmpz)
901905
fmpz_set((<fmpz>c).val, fac.constant)
902906
fmpz_mpoly_factor_clear(fac, self.ctx.val)
907+
908+
res.sort(key=_fmpz_mpoly_sort_key)
909+
903910
return c, res
904911

905912
def factor_squarefree(self):
@@ -1191,6 +1198,35 @@ cdef class fmpz_mpoly(flint_mpoly):
11911198
return list(stride), list(shift)
11921199

11931200

1201+
@cython.final
1202+
@cython.no_gc
1203+
cdef class _fmpz_mpoly_sort_key:
1204+
cdef fmpz_mpoly p
1205+
cdef ulong mult
1206+
1207+
def __init__(self, tuple fac_m):
1208+
self.p = fac_m[0]
1209+
self.mult = fac_m[1]
1210+
1211+
def __lt__(k1, _fmpz_mpoly_sort_key k2):
1212+
cdef slong nterms
1213+
cdef tuple monom1, monom2
1214+
cdef int coeff1, coeff2
1215+
if k1.mult != k2.mult:
1216+
return k1.mult < k2.mult
1217+
nterms = min(k1.p.val.length, k2.p.val.length)
1218+
for i in range(nterms):
1219+
monom1 = k1.p.monomial(i)
1220+
monom2 = k2.p.monomial(i)
1221+
if monom1 != monom2:
1222+
return monom1 < monom2
1223+
coeff1 = int(k1.p.coefficient(i))
1224+
coeff2 = int(k2.p.coefficient(i))
1225+
if coeff1 != coeff2:
1226+
return coeff1 < coeff2
1227+
return k1.p.val.length < k2.p.val.length
1228+
1229+
11941230
cdef class fmpz_mpoly_vec:
11951231
"""
11961232
A class representing a vector of fmpz_mpolys.

src/flint/types/nmod_mpoly.pyx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
cimport cython
2+
13
from flint.flint_base.flint_base cimport (
24
flint_mpoly,
35
flint_mod_mpoly_context,
@@ -841,7 +843,7 @@ cdef class nmod_mpoly(flint_mpoly):
841843
>>> (p1 * p2).factor()
842844
(6, [(z + 1, 1), (x + 1, 1), (x + 2, 1)])
843845
>>> (p2 * p1 * p2).factor()
844-
(7, [(z + 1, 2), (x + 2, 1), (x + 1, 2)])
846+
(7, [(x + 2, 1), (z + 1, 2), (x + 1, 2)])
845847
"""
846848
cdef:
847849
nmod_mpoly_factor_t fac
@@ -867,6 +869,9 @@ cdef class nmod_mpoly(flint_mpoly):
867869

868870
constant = nmod(fac.constant, self.ctx.modulus())
869871
nmod_mpoly_factor_clear(fac, self.ctx.val)
872+
873+
res.sort(key=_nmod_mpoly_sort_key)
874+
870875
return constant, res
871876

872877
def factor_squarefree(self):
@@ -1088,6 +1093,35 @@ cdef class nmod_mpoly(flint_mpoly):
10881093
return res
10891094

10901095

1096+
@cython.final
1097+
@cython.no_gc
1098+
cdef class _nmod_mpoly_sort_key:
1099+
cdef nmod_mpoly p
1100+
cdef ulong mult
1101+
1102+
def __init__(self, tuple fac_m):
1103+
self.p = fac_m[0]
1104+
self.mult = fac_m[1]
1105+
1106+
def __lt__(k1, _nmod_mpoly_sort_key k2):
1107+
cdef slong nterms
1108+
cdef tuple monom1, monom2
1109+
cdef int coeff1, coeff2
1110+
if k1.mult != k2.mult:
1111+
return k1.mult < k2.mult
1112+
nterms = min(k1.p.val.length, k2.p.val.length)
1113+
for i in range(nterms):
1114+
monom1 = k1.p.monomial(i)
1115+
monom2 = k2.p.monomial(i)
1116+
if monom1 != monom2:
1117+
return monom1 < monom2
1118+
coeff1 = k1.p.coefficient(i)
1119+
coeff2 = k2.p.coefficient(i)
1120+
if coeff1 != coeff2:
1121+
return coeff1 < coeff2
1122+
return k1.p.val.length < k2.p.val.length
1123+
1124+
10911125
cdef class nmod_mpoly_vec:
10921126
"""
10931127
A class representing a vector of nmod_mpolys.

0 commit comments

Comments
 (0)