# Ticket #12404: trac_12404.patch

File trac_12404.patch, 4.5 KB (added by saraedum, 10 years ago)

distinguish characteristic zero and nonzero

• ## sage/rings/polynomial/polynomial_element.pyx

```# HG changeset patch
# User Julian Rueth <julian.rueth@gmail.com>
Trac 12404: Distinguish zero and non-zero characteristic in is_squarefree for univariate polynomials.
More could be done for polynomials defined over perfect rings but this will go into another patch.

diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
index e5a7011..d25c3df 100644```
 a AUTHORS: -  Robert Bradshaw: Move Polynomial_generic_dense to Cython. -  Miguel Marco: Implemented resultant in the case where PARI fails. -  Miguel Marco: Implemented resultant in the case where PARI fails. -  Simon King: Use a faster way of conversion from the base ring. -  Julian Rueth (2012-05-25): Fixed is_squarefree() for imperfect fields. TESTS:: cdef class Polynomial(CommutativeAlgebraElement): def is_squarefree(self): """ Return True if this polynomial is square free. Return False if this polynomial is not square-free, i.e., if there is a non-unit `g` in the polynomial ring such that `g^2` divides ``self``. EXAMPLES:: sage: x = polygen(QQ) sage: R. = QQ[] sage: f = (x-1)*(x-2)*(x^2-5)*(x^17-3); f x^21 - 3*x^20 - 3*x^19 + 15*x^18 - 10*x^17 - 3*x^4 + 9*x^3 + 9*x^2 - 45*x + 30 sage: f.is_squarefree() True sage: (f*(x^2-5)).is_squarefree() False A generic implementation is available for polynomials defined over principal ideal domains of characteristic 0; the algorithm relies on gcd computations:: sage: R. = ZZ[] sage: f = 2*x; g = 4*x; h = 2*x^2 sage: f.is_squarefree() sage: (2*x).is_squarefree() True sage: g.is_squarefree() sage: (4*x).is_squarefree() False sage: (2*x^2).is_squarefree() False sage: R(0).is_squarefree() False sage: S. = QQ[] sage: R. = S[] sage: (2*x*y).is_squarefree() # R does not provide a gcd implementation Traceback (most recent call last): ... AttributeError: 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense' object has no attribute 'gcd' sage: (2*x*y^2).is_squarefree() False sage: h.is_squarefree() Over principal ideal domains of positive characteristic, we compute the square-free decomposition or a full factorization depending on which is available:: sage: K. = FunctionField(GF(3)) sage: R. = K[] sage: (x^3+2*x).is_squarefree() True sage: (x^3+2).is_squarefree() False sage: (x^3+t).is_squarefree() True sage: R(t^2).is_squarefree() True """ if self.parent().base_ring().is_field(): return self.derivative().gcd(self).degree() <= 0 return self.derivative().gcd(self).degree() <= 0 and self.content().is_squarefree() if self.parent().base_ring() not in sage.categories.principal_ideal_domains.PrincipalIdealDomains(): raise NotImplementedError("is_squarefree() is only implemented for polynomials over principal ideal domains") # a square-free polynomial has a square-free content if not self.parent().base_ring().is_field(): content = self.content() if content not in self.parent().base_ring(): content = content.gen() if not content.is_squarefree(): return False # separable polynomials are square-free if self.derivative().gcd(self).is_constant(): return True # for characteristic zero rings, square-free polynomials have to be separable if self.parent().characteristic().is_zero(): return False # over rings of positive characteristic, we rely on the square-free decomposition if available try: F = self.squarefree_decomposition() except NotImplementedError: F = self.factor() return all([e<=1 for (f,e) in F]) def radical(self): """