Skip to content

Commit 01e6418

Browse files
committed
Include nmod_mpoly and fmpz_mod_mpoly in factor test
1 parent 1abfb62 commit 01e6418

File tree

3 files changed

+52
-32
lines changed

3 files changed

+52
-32
lines changed

src/flint/test/test_all.py

+37-29
Original file line numberDiff line numberDiff line change
@@ -2481,41 +2481,41 @@ def test_division_matrix():
24812481
def _all_polys():
24822482
return [
24832483
# (poly_type, scalar_type, is_field)
2484-
(flint.fmpz_poly, flint.fmpz, False),
2485-
(flint.fmpq_poly, flint.fmpq, True),
2486-
(lambda *a: flint.nmod_poly(*a, 17), lambda x: flint.nmod(x, 17), True),
2484+
(flint.fmpz_poly, flint.fmpz, False, flint.fmpz(0)),
2485+
(flint.fmpq_poly, flint.fmpq, True, flint.fmpz(0)),
2486+
(lambda *a: flint.nmod_poly(*a, 17), lambda x: flint.nmod(x, 17), True, flint.fmpz(17)),
24872487
(lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(163)),
24882488
lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(163)),
2489-
True),
2489+
True, flint.fmpz(163)),
24902490
(lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(2**127 - 1)),
24912491
lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(2**127 - 1)),
2492-
True),
2492+
True, flint.fmpz(2**127 - 1)),
24932493
(lambda *a: flint.fmpz_mod_poly(*a, flint.fmpz_mod_poly_ctx(2**255 - 19)),
24942494
lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(2**255 - 19)),
2495-
True),
2495+
True, flint.fmpz(2**255 - 19)),
24962496
(lambda *a: flint.fq_default_poly(*a, flint.fq_default_poly_ctx(2**127 - 1)),
24972497
lambda x: flint.fq_default(x, flint.fq_default_ctx(2**127 - 1)),
2498-
True),
2498+
True, flint.fmpz(2**127 - 1)),
24992499
(lambda *a: flint.fq_default_poly(*a, flint.fq_default_poly_ctx(2**127 - 1, 2)),
25002500
lambda x: flint.fq_default(x, flint.fq_default_ctx(2**127 - 1, 2)),
2501-
True),
2501+
True, flint.fmpz(2**127 - 1)),
25022502
(lambda *a: flint.fq_default_poly(*a, flint.fq_default_poly_ctx(65537)),
25032503
lambda x: flint.fq_default(x, flint.fq_default_ctx(65537)),
2504-
True),
2504+
True, flint.fmpz(65537)),
25052505
(lambda *a: flint.fq_default_poly(*a, flint.fq_default_poly_ctx(65537, 5)),
25062506
lambda x: flint.fq_default(x, flint.fq_default_ctx(65537, 5)),
2507-
True),
2507+
True, flint.fmpz(65537)),
25082508
(lambda *a: flint.fq_default_poly(*a, flint.fq_default_poly_ctx(11)),
25092509
lambda x: flint.fq_default(x, flint.fq_default_ctx(11)),
2510-
True),
2510+
True, flint.fmpz(11)),
25112511
(lambda *a: flint.fq_default_poly(*a, flint.fq_default_poly_ctx(11, 5)),
25122512
lambda x: flint.fq_default(x, flint.fq_default_ctx(11, 5)),
2513-
True),
2513+
True, flint.fmpz(11)),
25142514
]
25152515

25162516

25172517
def test_polys():
2518-
for P, S, is_field in _all_polys():
2518+
for P, S, is_field, characteristic in _all_polys():
25192519
assert P([S(1)]) == P([1]) == P(P([1])) == P(1)
25202520

25212521
assert raises(lambda: P([None]), TypeError)
@@ -2750,37 +2750,41 @@ def setbad(obj, i, val):
27502750

27512751
def _all_mpolys():
27522752
return [
2753-
(flint.fmpz_mpoly, flint.fmpz_mpoly_ctx.get_context, flint.fmpz, False),
2754-
(flint.fmpq_mpoly, flint.fmpq_mpoly_ctx.get_context, flint.fmpq, True),
2753+
(flint.fmpz_mpoly, flint.fmpz_mpoly_ctx.get_context, flint.fmpz, False, flint.fmpz(0)),
2754+
(flint.fmpq_mpoly, flint.fmpq_mpoly_ctx.get_context, flint.fmpq, True, flint.fmpz(0)),
27552755
(
27562756
flint.fmpz_mod_mpoly,
27572757
lambda *args, **kwargs: flint.fmpz_mod_mpoly_ctx.get_context(*args, **kwargs, modulus=101),
27582758
lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(101)),
27592759
True,
2760+
flint.fmpz(101),
27602761
),
27612762
(
27622763
flint.fmpz_mod_mpoly,
27632764
lambda *args, **kwargs: flint.fmpz_mod_mpoly_ctx.get_context(*args, **kwargs, modulus=100),
27642765
lambda x: flint.fmpz_mod(x, flint.fmpz_mod_ctx(100)),
27652766
False,
2767+
flint.fmpz(100),
27662768
),
27672769
(
27682770
flint.nmod_mpoly,
27692771
lambda *args, **kwargs: flint.nmod_mpoly_ctx.get_context(*args, **kwargs, modulus=101),
27702772
lambda x: flint.nmod(x, 101),
27712773
True,
2774+
flint.fmpz(101),
27722775
),
27732776
(
27742777
flint.nmod_mpoly,
27752778
lambda *args, **kwargs: flint.nmod_mpoly_ctx.get_context(*args, **kwargs, modulus=100),
27762779
lambda x: flint.nmod(x, 100),
27772780
False,
2781+
flint.fmpz(100),
27782782
),
27792783
]
27802784

27812785

27822786
def test_mpolys():
2783-
for P, get_context, S, is_field in _all_mpolys():
2787+
for P, get_context, S, is_field, characteristic in _all_mpolys():
27842788

27852789
# Division under modulo will raise a flint exception if something is not invertible, crashing the program. We
27862790
# can't tell before what is invertible and what is not before hand so we always raise an exception, except for
@@ -3235,7 +3239,7 @@ def test_fmpz_mpoly_vec():
32353239

32363240
def _all_polys_mpolys():
32373241

3238-
for P, S, is_field in _all_polys():
3242+
for P, S, is_field, characteristic in _all_polys():
32393243
x = P([0, 1])
32403244
y = None
32413245
assert isinstance(x, (
@@ -3245,18 +3249,18 @@ def _all_polys_mpolys():
32453249
flint.fmpz_mod_poly,
32463250
flint.fq_default_poly,
32473251
))
3248-
characteristic_zero = isinstance(x, (flint.fmpz_poly, flint.fmpq_poly))
3249-
yield P, S, [x, y], is_field, characteristic_zero
3252+
yield P, S, [x, y], is_field, characteristic
32503253

3251-
for P, ctx_type, S, is_field in _all_mpolys():
3252-
ctx = ctx_type(2, flint.Ordering.lex, ["x", "y"])
3254+
for P, get_context, S, is_field, characteristic in _all_mpolys():
3255+
ctx = get_context(2, flint.Ordering.lex, nametup=("x", "y"))
32533256
x, y = ctx.gens()
32543257
assert isinstance(x, (
32553258
flint.fmpz_mpoly,
32563259
flint.fmpq_mpoly,
3260+
flint.nmod_mpoly,
3261+
flint.fmpz_mod_mpoly,
32573262
))
3258-
characteristic_zero = isinstance(x, (flint.fmpz_mpoly, flint.fmpq_mpoly))
3259-
yield P, S, [x, y], is_field, characteristic_zero
3263+
yield P, S, [x, y], is_field, characteristic
32603264

32613265

32623266
def test_factor_poly_mpoly():
@@ -3273,7 +3277,11 @@ def factor(p):
32733277
assert type(m) is int
32743278
return coeff, sorted(factors, key=lambda p: (p[1], str(p[0])))
32753279

3276-
for P, S, [x, y], is_field, characteristic_zero in _all_polys_mpolys():
3280+
for P, S, [x, y], is_field, characteristic in _all_polys_mpolys():
3281+
3282+
if characteristic != 0 and not characteristic.is_prime():
3283+
assert raises(lambda: x.factor(), DomainError)
3284+
continue
32773285

32783286
assert factor(0*x) == (S(0), [])
32793287
assert factor(0*x + 1) == (S(1), [])
@@ -3284,15 +3292,15 @@ def factor(p):
32843292
assert factor(x*(x+1)) == (S(1), [(x, 1), (x+1, 1)])
32853293
assert factor(2*(x+1)) == (S(2), [(x+1, 1)])
32863294

3287-
if characteristic_zero:
3295+
if characteristic == 0:
32883296
# primitive factors over Z for Z and Q.
32893297
assert factor(2*x+1) == (S(1), [(2*x+1, 1)])
32903298
else:
32913299
# monic factors over Z/pZ and GF(p^d)
32923300
assert factor(2*x+1) == (S(2), [(x+S(1)/2, 1)])
32933301

32943302
if is_field:
3295-
if characteristic_zero:
3303+
if characteristic == 0:
32963304
assert factor((2*x+1)/7) == (S(1)/7, [(2*x+1, 1)])
32973305
else:
32983306
assert factor((2*x+1)/7) == (S(2)/7, [(x+S(1)/2, 1)])
@@ -3302,13 +3310,13 @@ def factor(p):
33023310
assert factor(x*y+1) == (S(1), [(x*y+1, 1)])
33033311
assert factor(x*y) == (S(1), [(x, 1), (y, 1)])
33043312

3305-
if characteristic_zero:
3313+
if characteristic == 0:
33063314
assert factor(2*x + y) == (S(1), [(2*x + y, 1)])
33073315
else:
3308-
assert factor(2*x + y) == (S(1)/2, [(x + y/2, 1)])
3316+
assert factor(2*x + y) == (S(2), [(x + y/2, 1)])
33093317

33103318
if is_field:
3311-
if characteristic_zero:
3319+
if characteristic == 0:
33123320
assert factor((2*x+y)/7) == (S(1)/7, [(2*x+y, 1)])
33133321
else:
33143322
assert factor((2*x+y)/7) == (S(2)/7, [(x+y/2, 1)])

src/flint/types/fmpz_mod_mpoly.pyx

+7-1
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,12 @@ cdef class fmpz_mod_mpoly(flint_mpoly):
757757
fmpz_mod_mpoly_total_degree_fmpz((<fmpz> res).val, self.val, self.ctx.val)
758758
return res
759759

760+
def leading_coefficient(self):
761+
if fmpz_mod_mpoly_is_zero(self.val, self.ctx.val):
762+
return fmpz(0)
763+
else:
764+
return self.coefficient(0)
765+
760766
def repr(self):
761767
return f"{self.ctx}.from_dict({self.to_dict()})"
762768

@@ -846,7 +852,7 @@ cdef class fmpz_mod_mpoly(flint_mpoly):
846852
c = fmpz.__new__(fmpz)
847853
fmpz_set((<fmpz>c).val, &fac.exp[i])
848854

849-
res[i] = (u, c)
855+
res[i] = (u, int(c))
850856

851857
c = fmpz.__new__(fmpz)
852858
fmpz_set((<fmpz>c).val, fac.constant)

src/flint/types/nmod_mpoly.pyx

+8-2
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,12 @@ cdef class nmod_mpoly(flint_mpoly):
733733
nmod_mpoly_total_degree_fmpz((<fmpz> res).val, self.val, self.ctx.val)
734734
return res
735735

736+
def leading_coefficient(self):
737+
if nmod_mpoly_is_zero(self.val, self.ctx.val):
738+
return nmod(0, self.ctx.modulus())
739+
else:
740+
return nmod(self.coefficient(0), self.ctx.modulus())
741+
736742
def repr(self):
737743
return f"{self.ctx}.from_dict({self.to_dict()})"
738744

@@ -822,9 +828,9 @@ cdef class nmod_mpoly(flint_mpoly):
822828
c = fmpz.__new__(fmpz)
823829
fmpz_set((<fmpz>c).val, &fac.exp[i])
824830

825-
res[i] = (u, c)
831+
res[i] = (u, int(c))
826832

827-
constant = fac.constant
833+
constant = nmod(fac.constant, self.ctx.modulus())
828834
nmod_mpoly_factor_clear(fac, self.ctx.val)
829835
return constant, res
830836

0 commit comments

Comments
 (0)