Ticket #9054: trac_9054-part7.patch

File trac_9054-part7.patch, 7.5 KB (added by was, 7 years ago)

polynomial factorization!

  • sage/rings/function_field/function_field.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1275000774 25200
    # Node ID 11bc1c46e91ccbbfc86b09685a8fe0d7ef1a8d4e
    # Parent  e07f7bffaadce6b1d909ece2e7b491bcb84a5ba7
    trac 9054 -- part 7 -- univ polynomial factoring over rational function fields
    
    diff -r e07f7bffaadc -r 11bc1c46e91c sage/rings/function_field/function_field.py
    a b  
    7373        sage: isinstance(K, sage.rings.function_field.function_field.FunctionField)
    7474        True
    7575    """
     76    def characteristic(self):
     77        """
     78        Return the characteristic of this function field.
     79
     80        EXAMPLES::
     81
     82            sage: R.<t> = FunctionField(QQ)
     83            sage: R.characteristic()
     84            0
     85            sage: R.<t> = FunctionField(GF(7))
     86            sage: R.characteristic()
     87            7       
     88        """
     89        return self.constant_field().characteristic()
     90   
    7691    def extension(self, f, names=None):
    7792        """
    7893        Create an extension L = K[y]/(f(y)) of a function field,
     
    188203        if isinstance(R, FunctionFieldOrder) and R.fraction_field() == self:
    189204            return True
    190205        return False
    191    
     206
     207    def _factor_univariate_polynomial(self, f):
     208        raise NotImplementedError
    192209
    193210class FunctionField_polymod(FunctionField):
    194211    """
     
    679696            return function_field_element.FunctionFieldElement_rational(self, self._field(x.element()))
    680697        return function_field_element.FunctionFieldElement_rational(self, self._field(x))
    681698
     699    # nonoptimized
     700    def _to_bivariate_polynomial(self, f):
     701        """
     702        Convert f from a univariate polynomial over the rational function
     703        field into a bivariate polynomial and a denominator.
     704
     705        INPUT:
     706
     707            - f -- a univariate polynomial over self.
     708
     709        OUTPUT:
     710
     711            - 2-variate polynomial, denominator
     712
     713        EXAMPLES::
     714       
     715            sage: R.<t> = FunctionField(GF(7))
     716            sage: S.<X> = R[]
     717            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     718            sage: R._to_bivariate_polynomial(f)
     719            (x^7*t^2 - x^4*t^5 - x^3 + t^3, t^3)       
     720        """
     721        v = f.list()
     722        from sage.rings.arith import LCM
     723        denom = LCM([a.denominator() for a in v])
     724        S = denom.parent()
     725        x,t = S.base_ring()['x,t'].gens()
     726        phi = S.hom([t])
     727        return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom
     728
     729    def _factor_univariate_polynomial(self, f, proof=True):
     730        """
     731        Factor the univariate polynomial f over self.
     732
     733        EXAMPLES::
     734
     735        We do a factorization over the function field over the rationals::
     736
     737            sage: R.<t> = FunctionField(QQ)
     738            sage: S.<X> = R[]
     739            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     740            sage: f.factor()             # indirect doctest
     741            (1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2)
     742            sage: f.factor().prod() == f
     743            True       
     744
     745        You must pass in proof=False over finite fields, due to
     746        Singular's factoring algorithm being incomplete::
     747
     748            sage: R.<t> = FunctionField(GF(7))
     749            sage: S.<X> = R[]
     750            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     751            sage: f.factor()
     752            Traceback (most recent call last):
     753            ...
     754            NotImplementedError: proof = True factorization not implemented.  Call factor with proof=False.
     755            sage: f.factor(proof=False)
     756            (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t)
     757            sage: f.factor(proof=False).prod() == f
     758            True
     759
     760        Factoring over a function field over a non-prime finite field::
     761
     762            sage: k.<a> = GF(9)
     763            sage: R.<t> = FunctionField(k)
     764            sage: S.<X> = R[]
     765            sage: f = (1/t)*(X^3 - a*t^3)
     766            sage: f.factor(proof=False)
     767            (1/t) * (X + (a + 2)*t)^3
     768            sage: f.factor(proof=False).prod() == f
     769            True
     770        """
     771        F, d = self._to_bivariate_polynomial(f)
     772        fac = F.factor(proof=proof)
     773        x = f.parent().gen()
     774        t = f.parent().base_ring().gen()
     775        phi = F.parent().hom([x, t])
     776        v = [(phi(P),e) for P, e in fac]
     777        unit = phi(fac.unit())/d
     778        w = []
     779        for a, e in v:
     780            c = a.leading_coefficient()
     781            a = a/c
     782            unit *= (c**e)
     783            w.append((a,e))
     784        from sage.structure.factorization import Factorization
     785        return Factorization(w, unit=unit)
     786
    682787    def polynomial_ring(self):
    683788        """
    684789        Return polynomial ring underlying this function field.
  • sage/rings/function_field/function_field_element.pyx

    diff -r e07f7bffaadc -r 11bc1c46e91c sage/rings/function_field/function_field_element.pyx
    a b  
    348348        FieldElement.__init__(self, parent)
    349349        self._x = x
    350350
     351    # nonoptimized
     352
    351353    def element(self):
    352354        """
    353355        Return the underlying fraction field element that represents this element.
  • sage/rings/function_field/todo.txt

    diff -r e07f7bffaadc -r 11bc1c46e91c sage/rings/function_field/todo.txt
    a b  
    11TODO:
    22
    33[ ] ideals
    4 [ ] polynomial factoring of any univariate poly over a function field: reduce to bivariate over constant field?
     4[ ] reduction algorithm
     5
     6[ ] polynomial factoring of any univariate poly over a non-rational function field
     7
    58[ ] checking irreducibility in FunctionField_polymod constructor
    6 
    79[ ] Docstring headers for each file with description of content of file
    810[ ] copyright headers
    911[ ] pickle doctests
     
    1214[ ] a command FunctionField to make a new function field from anything.
    1315[ ] method function_field() on algebraic curves, that give back a corresponding function field object.
    1416
     17
    1518DONE:
     19[x] polynomial factoring of any univariate poly over a rational function field: reduce to bivariate over constant field?
    1620[x] conversion back and forth between a free module over base
    1721[x] random element
    1822[x] numerator, denominator
  • sage/rings/polynomial/polynomial_element.pyx

    diff -r e07f7bffaadc -r 11bc1c46e91c sage/rings/polynomial/polynomial_element.pyx
    a b  
    3838import sage.rings.finite_rings.integer_mod_ring
    3939import sage.rings.complex_field
    4040import sage.rings.fraction_field_element
     41import sage.rings.function_field
    4142import sage.rings.infinity as infinity
    4243#import sage.misc.misc as misc
    4344from sage.misc.sage_eval import sage_eval
     
    23002301                X[i] = c
    23012302        return X
    23022303
    2303     def factor(self):
     2304    def factor(self, proof=True):
    23042305        r"""
    23052306        Return the factorization of self over the base ring of this
    23062307        polynomial. Factoring polynomials over
     
    27342735            else:
    27352736                G = self._pari_with_name('x').factor()
    27362737
     2738        elif sage.rings.function_field.function_field.is_FunctionField(R):
     2739            return R._factor_univariate_polynomial(self, proof=proof)
     2740
    27372741        #elif padic_field.is_pAdicField(R):
    27382742        #    G = list(self._pari_with_name('x').factorpadic(R.prime(), R.prec()))
    27392743