Skip to content

Commit c7a564c

Browse files
committed
Test all poly types can factor the zero poly
1 parent 8c4cc87 commit c7a564c

File tree

5 files changed

+38
-6
lines changed

5 files changed

+38
-6
lines changed

src/flint/test/test_all.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,7 +3279,10 @@ def factor(p):
32793279

32803280
for P, S, [x, y], is_field, characteristic_zero in _all_polys_mpolys():
32813281

3282+
assert factor(0*x) == (S(0), [])
3283+
assert factor(0*x + 1) == (S(1), [])
32823284
assert factor(x) == (S(1), [(x, 1)])
3285+
assert factor(-x) == (S(-1), [(x, 1)])
32833286
assert factor(x**2) == (S(1), [(x, 2)])
32843287
assert factor(x*(x+1)) == (S(1), [(x, 1), (x+1, 1)])
32853288
assert factor(2*(x+1)) == (S(2), [(x+1, 1)])
@@ -3293,10 +3296,8 @@ def factor(p):
32933296

32943297
if is_field:
32953298
if characteristic_zero:
3296-
# primitive factors over Z for Z and Q.
32973299
assert factor((2*x+1)/7) == (S(1)/7, [(2*x+1, 1)])
32983300
else:
3299-
# monic factors over Z/pZ and GF(p^d)
33003301
assert factor((2*x+1)/7) == (S(2)/7, [(x+S(1)/2, 1)])
33013302

33023303
if y is not None:
@@ -3305,12 +3306,16 @@ def factor(p):
33053306
assert factor(x*y) == (S(1), [(x, 1), (y, 1)])
33063307

33073308
if characteristic_zero:
3308-
# primitive factors over Z for Z and Q.
33093309
assert factor(2*x + y) == (S(1), [(2*x + y, 1)])
33103310
else:
3311-
# monic factors over Z/pZ and GF(p^d)
33123311
assert factor(2*x + y) == (S(1)/2, [(x + y/2, 1)])
33133312

3313+
if is_field:
3314+
if characteristic_zero:
3315+
assert factor((2*x+y)/7) == (S(1)/7, [(2*x+y, 1)])
3316+
else:
3317+
assert factor((2*x+y)/7) == (S(2)/7, [(x+y/2, 1)])
3318+
33143319

33153320
def _all_matrices():
33163321
"""Return a list of matrix types and scalar types."""

src/flint/types/fmpq_mpoly.pyx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,12 @@ cdef class fmpq_mpoly(flint_mpoly):
858858
fmpq_mpoly_total_degree_fmpz((<fmpz> res).val, self.val, self.ctx.val)
859859
return res
860860

861+
def leading_coefficient(self):
862+
if fmpq_mpoly_is_zero(self.val, self.ctx.val):
863+
return fmpq(0)
864+
else:
865+
return self.coefficient(0)
866+
861867
def repr(self):
862868
return f"{self.ctx}.from_dict({self.to_dict()})"
863869

src/flint/types/fmpz_mod_poly.pyx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,6 +1798,17 @@ cdef class fmpz_mod_poly(flint_poly):
17981798
if not self.ctx.is_prime():
17991799
raise NotImplementedError("factor algorithm assumes that the modulus is prime")
18001800

1801+
# XXX: fmpz_mod_poly_factor with modulus 163 crashes on the zero poly:
1802+
#
1803+
# Exception (fmpz_mod_poly_powmod_fmpz_binexp). Divide by zero
1804+
#
1805+
# We handle this special case first:
1806+
cdef fmpz_mod zero
1807+
if self.is_zero():
1808+
zero = fmpz_mod.__new__(fmpz_mod)
1809+
zero.ctx = self.ctx.mod
1810+
return (zero, [])
1811+
18011812
fmpz_mod_poly_factor_init(fac, self.ctx.mod.val)
18021813
if algorithm == None:
18031814
fmpz_mod_poly_factor(fac, self.val, self.ctx.mod.val)

src/flint/types/fmpz_mpoly.pyx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,12 @@ cdef class fmpz_mpoly(flint_mpoly):
836836
fmpz_mpoly_total_degree_fmpz((<fmpz> res).val, self.val, self.ctx.val)
837837
return res
838838

839+
def leading_coefficient(self):
840+
if fmpz_mpoly_is_zero(self.val, self.ctx.val):
841+
return fmpz(0)
842+
else:
843+
return self.coefficient(0)
844+
839845
def repr(self):
840846
return f"{self.ctx}.from_dict({self.to_dict()})"
841847

src/flint/types/nmod_poly.pyx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,15 +235,19 @@ cdef class nmod_poly(flint_poly):
235235
>>> f.leading_coefficient()
236236
133
237237
"""
238+
cdef ulong cu
239+
cdef slong d
238240
cdef nmod c
239241

240242
d = self.degree()
241243
if d < 0:
242-
return 0
244+
cu = 0
245+
else:
246+
cu = nmod_poly_get_coeff_ui(self.val, d)
243247

244248
c = nmod.__new__(nmod)
245249
c.mod = self.val.mod
246-
c.val = nmod_poly_get_coeff_ui(self.val, d)
250+
c.val = cu
247251

248252
return c
249253

0 commit comments

Comments
 (0)