Skip to content

Commit eb12dfd

Browse files
committed
Test all poly types can factor the zero poly
1 parent 20f5eba commit eb12dfd

5 files changed

Lines changed: 38 additions & 6 deletions

File tree

src/flint/test/test_all.py

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

32093209
for P, S, [x, y], is_field, characteristic_zero in _all_polys_mpolys():
32103210

3211+
assert factor(0*x) == (S(0), [])
3212+
assert factor(0*x + 1) == (S(1), [])
32113213
assert factor(x) == (S(1), [(x, 1)])
3214+
assert factor(-x) == (S(-1), [(x, 1)])
32123215
assert factor(x**2) == (S(1), [(x, 2)])
32133216
assert factor(x*(x+1)) == (S(1), [(x, 1), (x+1, 1)])
32143217
assert factor(2*(x+1)) == (S(2), [(x+1, 1)])
@@ -3222,10 +3225,8 @@ def factor(p):
32223225

32233226
if is_field:
32243227
if characteristic_zero:
3225-
# primitive factors over Z for Z and Q.
32263228
assert factor((2*x+1)/7) == (S(1)/7, [(2*x+1, 1)])
32273229
else:
3228-
# monic factors over Z/pZ and GF(p^d)
32293230
assert factor((2*x+1)/7) == (S(2)/7, [(x+S(1)/2, 1)])
32303231

32313232
if y is not None:
@@ -3234,12 +3235,16 @@ def factor(p):
32343235
assert factor(x*y) == (S(1), [(x, 1), (y, 1)])
32353236

32363237
if characteristic_zero:
3237-
# primitive factors over Z for Z and Q.
32383238
assert factor(2*x + y) == (S(1), [(2*x + y, 1)])
32393239
else:
3240-
# monic factors over Z/pZ and GF(p^d)
32413240
assert factor(2*x + y) == (S(1)/2, [(x + y/2, 1)])
32423241

3242+
if is_field:
3243+
if characteristic_zero:
3244+
assert factor((2*x+y)/7) == (S(1)/7, [(2*x+y, 1)])
3245+
else:
3246+
assert factor((2*x+y)/7) == (S(2)/7, [(x+y/2, 1)])
3247+
32433248

32443249
def _all_matrices():
32453250
"""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
@@ -856,6 +856,12 @@ cdef class fmpq_mpoly(flint_mpoly):
856856
fmpq_mpoly_total_degree_fmpz((<fmpz> res).val, self.val, self.ctx.val)
857857
return res
858858

859+
def leading_coefficient(self):
860+
if fmpq_mpoly_is_zero(self.val, self.ctx.val):
861+
return fmpq(0)
862+
else:
863+
return self.coefficient(0)
864+
859865
def repr(self):
860866
return f"{self.ctx}.from_dict({self.to_dict()})"
861867

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
@@ -838,6 +838,12 @@ cdef class fmpz_mpoly(flint_mpoly):
838838
fmpz_mpoly_total_degree_fmpz((<fmpz> res).val, self.val, self.ctx.val)
839839
return res
840840

841+
def leading_coefficient(self):
842+
if fmpz_mpoly_is_zero(self.val, self.ctx.val):
843+
return fmpz(0)
844+
else:
845+
return self.coefficient(0)
846+
841847
def repr(self):
842848
return f"{self.ctx}.from_dict({self.to_dict()})"
843849

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)