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 b AUTHORS: 
    99
    1010-  Robert Bradshaw: Move Polynomial_generic_dense to Cython.
    1111
    12 -  Miguel Marco: Implemented resultant in the case where PARI fails. 
     12-  Miguel Marco: Implemented resultant in the case where PARI fails.
    1313
    1414-  Simon King: Use a faster way of conversion from the base ring.
    1515
     16-  Julian Rueth (2012-05-25): Fixed is_squarefree() for imperfect fields.
    1617
    1718TESTS::
    1819
    cdef class Polynomial(CommutativeAlgebraElement): 
    56165617       
    56175618    def is_squarefree(self):
    56185619        """
    5619         Return True if this polynomial is square free.
    5620        
     5620        Return False if this polynomial is not square-free, i.e., if there is a
     5621        non-unit `g` in the polynomial ring such that `g^2` divides ``self``.
     5622
    56215623        EXAMPLES::
    56225624       
    5623             sage: x = polygen(QQ)
     5625            sage: R.<x> = QQ[]
    56245626            sage: f = (x-1)*(x-2)*(x^2-5)*(x^17-3); f
    56255627            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
    56265628            sage: f.is_squarefree()
    56275629            True
    56285630            sage: (f*(x^2-5)).is_squarefree()
    56295631            False
     5632
     5633        A generic implementation is available for polynomials defined over
     5634        principal ideal domains of characteristic 0; the algorithm relies on
     5635        gcd computations::
     5636
    56305637            sage: R.<x> = ZZ[]
    5631             sage: f = 2*x; g = 4*x; h = 2*x^2
    5632             sage: f.is_squarefree()
     5638            sage: (2*x).is_squarefree()
    56335639            True
    5634             sage: g.is_squarefree()
     5640            sage: (4*x).is_squarefree()
     5641            False
     5642            sage: (2*x^2).is_squarefree()
     5643            False
     5644            sage: R(0).is_squarefree()
     5645            False
     5646
     5647            sage: S.<y> = QQ[]
     5648            sage: R.<x> = S[]
     5649            sage: (2*x*y).is_squarefree() # R does not provide a gcd implementation
     5650            Traceback (most recent call last):
     5651            ...
     5652            AttributeError: 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense' object has no attribute 'gcd'
     5653            sage: (2*x*y^2).is_squarefree()
    56355654            False
    5636             sage: h.is_squarefree()
     5655
     5656        Over principal ideal domains of positive characteristic, we compute the
     5657        square-free decomposition or a full factorization depending on which is
     5658        available::
     5659
     5660            sage: K.<t> = FunctionField(GF(3))
     5661            sage: R.<x> = K[]
     5662            sage: (x^3+2*x).is_squarefree()
     5663            True
     5664            sage: (x^3+2).is_squarefree()
    56375665            False
     5666            sage: (x^3+t).is_squarefree()
     5667            True
     5668            sage: R(t^2).is_squarefree()
     5669            True
     5670
    56385671        """
    5639         if self.parent().base_ring().is_field():
    5640             return self.derivative().gcd(self).degree() <= 0
    5641         return self.derivative().gcd(self).degree() <= 0 and self.content().is_squarefree()
     5672        if self.parent().base_ring() not in sage.categories.principal_ideal_domains.PrincipalIdealDomains():
     5673            raise NotImplementedError("is_squarefree() is only implemented for polynomials over principal ideal domains")
     5674
     5675        # a square-free polynomial has a square-free content
     5676        if not self.parent().base_ring().is_field():
     5677            content = self.content()
     5678            if content not in self.parent().base_ring():
     5679                content = content.gen()
     5680            if not content.is_squarefree():
     5681                return False
     5682
     5683        # separable polynomials are square-free
     5684        if self.derivative().gcd(self).is_constant():
     5685            return True
     5686
     5687        # for characteristic zero rings, square-free polynomials have to be separable
     5688        if self.parent().characteristic().is_zero():
     5689            return False
     5690
     5691        # over rings of positive characteristic, we rely on the square-free decomposition if available
     5692        try:
     5693            F = self.squarefree_decomposition()
     5694        except NotImplementedError:
     5695            F = self.factor()
     5696        return all([e<=1 for (f,e) in F])
    56425697       
    56435698    def radical(self):
    56445699        """