Ticket #9054: trac_9054-part1-12.patch

File trac_9054-part1-12.patch, 106.5 KB (added by was, 7 years ago)

flattened patch that incorporates all of patches 1-12 above into a single patch.

  • module_list.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1274873455 25200
    # Node ID abe865452a9d73ba434638f2e076ece4aa5e992f
    # Parent  33ff7b9bec51847e00a3656de5a35f2d73e4f463
    trac 9054 -- create a class for basic function_field arithmetic for Sage
    * * *
    trac 9054 -- part 2: fully documented function fields; added vector space structure
    * * *
    [mq]: trac-9054-part3.patch
    * * *
    [mq]: trac_9054-part4.patch
    * * *
    Cythonize function field elements.
    * * *
    [mq]: trac_9054-part6.patch
    * * *
    trac 9054 -- part 7 -- univ polynomial factoring over rational function fields
    * * *
    trac 9054 (part 8): work on ideals and orders; in particular got basic capabilities all working and fix lots of linear algebra
    * * *
    trac 9054 (part 9): inverses of fractional ideals; hermite form for general matrices; some little function field bugfixes.
    * * *
    trac 9054 (part 10): morphisms of function fields
    * * *
    trac 9054 -- part 11: misc fixes; integrality, etc.
    * * *
    #9051 - function fields: valuation, sqrt, is_finite, etc.
    
    diff --git a/module_list.py b/module_list.py
    a b  
    11781178
    11791179        ################################
    11801180        ##
     1181        ## sage.rings.function_field
     1182        ##
     1183        ################################
     1184
     1185    Extension('sage.rings.function_field.function_field_element',
     1186              sources = ['sage/rings/function_field/function_field_element.pyx']),
     1187
     1188        ################################
     1189        ##
    11811190        ## sage.rings.number_field
    11821191        ##
    11831192        ################################
  • new file sage/categories/function_fields.py

    diff --git a/sage/categories/function_fields.py b/sage/categories/function_fields.py
    new file mode 100644
    - +  
     1r"""
     2FunctionFields
     3"""
     4#*****************************************************************************
     5#  Copyright (C) 2005      David Kohel <kohel@maths.usyd.edu>
     6#                          William Stein <wstein@math.ucsd.edu>
     7#                2008      Teresa Gomez-Diaz (CNRS) <Teresa.Gomez-Diaz@univ-mlv.fr>
     8#                2008-2009 Nicolas M. Thiery <nthiery at users.sf.net>
     9#
     10#  Distributed under the terms of the GNU General Public License (GPL)
     11#                  http://www.gnu.org/licenses/
     12#******************************************************************************
     13
     14from sage.categories.category import Category
     15from sage.misc.cachefunc import cached_method
     16from sage.categories.basic import Fields
     17from sage.rings.field import is_Field
     18
     19class FunctionFields(Category):
     20    r"""
     21    The category of function fields.
     22
     23    EXAMPLES:
     24
     25    We create the category of function fields::
     26
     27        sage: C = FunctionFields()
     28        sage: C
     29        Category of function fields
     30
     31    TESTS::
     32
     33        sage: TestSuite(FunctionFields()).run()
     34    """
     35
     36    @cached_method
     37    def super_categories(self):
     38        """
     39        EXAMPLES::
     40
     41            sage: FunctionFields().super_categories()
     42            [Category of fields]
     43        """
     44        return[Fields()]
     45
     46    def __contains__(self, x):
     47        r"""
     48        Returns True if ``x`` is a function field.
     49
     50        EXAMPLES::
     51
     52        """
     53        import sage.rings.all
     54        return sage.rings.all.is_FunctionField(x)
     55
     56    def _call_(self, x):
     57        r"""
     58        Constructs an object in this category from the data in ``x``,
     59        or throws a TypeError.
     60
     61        EXAMPLES::
     62
     63            sage: C = FunctionFields()
     64
     65        """
     66        try:
     67            return x.function_field()
     68        except AttributeError:
     69            raise  TypeError, "unable to canonically associate a function field to %s"%x
     70
     71
     72    class ParentMethods:
     73        pass
     74
     75    class ElementMethods:
     76        pass
  • sage/matrix/matrix2.pyx

    diff --git a/sage/matrix/matrix2.pyx b/sage/matrix/matrix2.pyx
    a b  
    42764276        else:
    42774277            try:
    42784278                a, d, p = self._echelon_form_PID()
    4279             except TypeError:
    4280                 raise NotImplementedError, "echelon form over %s not yet implemented"%self.base_ring()
     4279            except TypeError, msg:
     4280                raise NotImplementedError, "%s\nechelon form over %s not yet implemented"%(msg, self.base_ring())
    42814281
    42824282            for c from 0 <= c < self.ncols():
    42834283               for r from 0 <= r < self.nrows():
     
    44034403                    kwds['algorithm'] = algorithm
    44044404                return self._echelonize_ring(**kwds)
    44054405        except ArithmeticError, msg:
    4406             raise NotImplementedError, "Echelon form not implemented over '%s'."%self.base_ring()
     4406            raise NotImplementedError, "%s\nEchelon form not implemented over '%s'."%(msg,self.base_ring())
    44074407
    44084408    def echelon_form(self, algorithm="default", cutoff=0, **kwds):
    44094409        """
     
    68586858        dp, up, vp = _smith_diag(d)
    68596859        return dp,up*u,v*vp
    68606860
     6861    def hermite_form(self, include_zero_rows=True, transformation=False):
     6862        """
     6863        Return the Hermite form of self, if it is defined.
     6864
     6865        INPUT:
     6866
     6867            - ``include_zero_rows`` -- bool (default: True); if False
     6868              the zero rows in the output matrix are deleted.
     6869
     6870            - ``transformation`` -- bool (default: False) a matrix U such that U*self == H.
     6871
     6872        OUTPUT:
     6873
     6874            - matrix H
     6875            - (optional) transformation matrix U such that U*self == H, possibly with zero
     6876              rows deleted...
     6877       
     6878
     6879        EXAMPLES::
     6880
     6881            sage: M = FunctionField(GF(7),'x').maximal_order()
     6882            sage: K.<x> = FunctionField(GF(7)); M = K.maximal_order()
     6883            sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2])
     6884            sage: A.hermite_form()
     6885            [      x       1     2*x]
     6886            [      0       x 5*x + 2]
     6887            sage: A.hermite_form(transformation=True)
     6888            (
     6889            [      x       1     2*x]  [1 0]
     6890            [      0       x 5*x + 2], [6 1]
     6891            )
     6892            sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x])
     6893            sage: A.hermite_form(transformation=True, include_zero_rows=False)
     6894            ([  x   1 2*x], [1 0])
     6895            sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U
     6896            (
     6897            [  x   1 2*x]  [1 0]
     6898            [  0   0   0], [5 1]
     6899            )
     6900            sage: U*A == H
     6901            True
     6902            sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False)
     6903            sage: U*A
     6904            [  x   1 2*x]
     6905            sage: U*A == H
     6906            True
     6907        """
     6908        left, H, pivots = self._echelon_form_PID()
     6909        if not include_zero_rows:
     6910            i = H.nrows() - 1
     6911            while H.row(i) == 0:
     6912                i -= 1
     6913            H = H[:i+1]
     6914            if transformation:
     6915                left = left[:i+1]
     6916        if transformation:
     6917            return H, left
     6918        else:
     6919            return H
     6920
    68616921    def _echelon_form_PID(self):
    68626922        r"""
    68636923        Return a triple (left, a, pivots) where left*self == a and a is row
     
    70957155        if a[k,0] not in I:
    70967156            try:
    70977157                v = R.ideal(a[0,0], a[k,0]).gens_reduced()
    7098             except:
    7099                 raise ArithmeticError, "Can't create ideal on %s and %s" % (a[0,0], a[k,0])
     7158            except Exception, msg:
     7159                raise ArithmeticError, "%s\nCan't create ideal on %s and %s" % (msg, a[0,0], a[k,0])
    71007160            if len(v) > 1:
    71017161                raise ArithmeticError, "Ideal %s not principal" %  R.ideal(a[0,0], a[k,0])
    71027162            B = v[0]
  • sage/modules/free_module.py

    diff --git a/sage/modules/free_module.py b/sage/modules/free_module.py
    a b  
    48054805        """
    48064806        if len(B) == 0:
    48074807            return 1
    4808         d = sage.rings.integer.Integer(B[0].denominator())
     4808        d = B[0].denominator()
    48094809        for x in B[1:]:
    48104810            d = d.lcm(x.denominator())
    48114811        return d
  • sage/rings/all.py

    diff --git a/sage/rings/all.py b/sage/rings/all.py
    a b  
    6767# Number field
    6868from number_field.all import *
    6969
     70# Function field
     71from function_field.all import *
     72
    7073# p-adic field
    7174from padics.all import *
    7275from padics.padic_printing import _printer_defaults as padic_printing
  • new file sage/rings/function_field/__init__.py

    diff --git a/sage/rings/function_field/__init__.py b/sage/rings/function_field/__init__.py
    new file mode 100644
    - +  
     1# Function fields
  • new file sage/rings/function_field/all.py

    diff --git a/sage/rings/function_field/all.py b/sage/rings/function_field/all.py
    new file mode 100644
    - +  
     1from function_field import is_FunctionField
     2from constructor import FunctionField
     3
     4
  • new file sage/rings/function_field/constructor.py

    diff --git a/sage/rings/function_field/constructor.py b/sage/rings/function_field/constructor.py
    new file mode 100644
    - +  
     1import function_field
     2
     3def FunctionField(X, names=None):
     4    """
     5    Return the function field defined by X.
     6
     7    INPUT:
     8
     9        - `X` -- a field; return the function field in one variable over X.
     10
     11        - ``names`` -- name of variable as a string
     12   
     13    EXAMPLES::
     14
     15        sage: FunctionField(QQ,'alpha')
     16        Rational function field in alpha over Rational Field
     17        sage: K.<alpha> = FunctionField(GF(7)); K
     18        Rational function field in alpha over Finite Field of size 7
     19    """
     20    return function_field.RationalFunctionField(X, names=names)
     21   
  • new file sage/rings/function_field/function_field.py

    diff --git a/sage/rings/function_field/function_field.py b/sage/rings/function_field/function_field.py
    new file mode 100644
    - +  
     1r"""
     2Function fields
     3
     4EXAMPLES::
     5
     6We create an extension of a rational function fields, and do some
     7simple arithmetic in it::
     8
     9    sage: K.<x> = FunctionField(GF(5^2,'a')); K
     10    Rational function field in x over Finite Field in a of size 5^2
     11    sage: R.<y> = K[]
     12    sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     13    Function field in y defined by y^5 + 3*x*y + (4*x^4 + 4)/x
     14    sage: y^4
     15    y^4
     16    sage: y^5
     17    2*x*y + (x^4 + 1)/x
     18    sage: a = 1/y; a
     19    (4*x/(4*x^4 + 4))*y^4 + 2*x^2/(4*x^4 + 4)
     20    sage: a * y
     21    1
     22
     23We next make an extension of the above function field, illustrating
     24that arithmetic with a tower of 3 fields is fully supported::
     25
     26    sage: S.<t> = L[]
     27    sage: M.<t> = L.extension(t^2 - x*y)
     28    sage: M
     29    Function field in t defined by t^2 + 4*x*y
     30    sage: t^2
     31    x*y
     32    sage: 1/t
     33    ((1/(x^4 + 1))*y^4 + 2*x/(4*x^4 + 4))*t
     34    sage: M.base_field()
     35    Function field in y defined by y^5 + 3*x*y + (4*x^4 + 4)/x
     36    sage: M.base_field().base_field()
     37    Rational function field in x over Finite Field in a of size 5^2
     38   
     39"""
     40
     41from sage.structure.category_object import CategoryObject
     42from sage.rings.ring import Field
     43from sage.rings.integer_ring import ZZ
     44from sage.structure.parent_gens import ParentWithGens
     45import function_field_element
     46
     47from sage.categories.function_fields import FunctionFields
     48CAT = FunctionFields()
     49
     50import maps
     51
     52def is_FunctionField(x):
     53    """
     54    Return True if x is of function field type.
     55
     56    EXAMPLES::
     57   
     58        sage: from sage.rings.function_field.all import is_FunctionField
     59        sage: is_FunctionField(QQ)
     60        False
     61        sage: is_FunctionField(FunctionField(QQ,'t'))
     62        True
     63    """
     64    return isinstance(x, FunctionField)
     65
     66
     67class FunctionField(Field):
     68    """
     69    The abstract base class for all function fields.
     70   
     71    EXAMPLES::
     72   
     73        sage: K.<x> = FunctionField(QQ)
     74        sage: isinstance(K, sage.rings.function_field.function_field.FunctionField)
     75        True
     76    """
     77    def characteristic(self):
     78        """
     79        Return the characteristic of this function field.
     80
     81        EXAMPLES::
     82
     83            sage: R.<t> = FunctionField(QQ)
     84            sage: R.characteristic()
     85            0
     86            sage: R.<t> = FunctionField(GF(7))
     87            sage: R.characteristic()
     88            7       
     89        """
     90        return self.constant_field().characteristic()
     91   
     92    def is_finite(self):
     93        """
     94        Return whether this function field is finite, which it is not.
     95
     96        EXAMPLES::
     97
     98            sage: R.<t> = FunctionField(QQ)
     99            sage: R.is_finite()
     100            False
     101            sage: R.<t> = FunctionField(GF(7))
     102            sage: R.is_finite()
     103            False
     104        """
     105        return False
     106   
     107    def extension(self, f, names=None):
     108        """
     109        Create an extension L = K[y]/(f(y)) of a function field,
     110        defined by a univariate polynomial in one variable over this
     111        function field K.
     112
     113        INPUT:
     114       
     115            - `f` -- a univariate polynomial over self
     116            - ``names`` -- None or string or length-1 tuple
     117
     118        OUTPUT:
     119
     120            - a function field
     121       
     122        EXAMPLES::
     123       
     124            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     125            sage: K.extension(y^5 - x^3 - 3*x + x*y)
     126            Function field in y defined by y^5 + x*y - x^3 - 3*x
     127
     128
     129        A nonintegral defining polynomial::
     130
     131            sage: K.<t> = FunctionField(QQ); R.<y> = K[]
     132            sage: K.extension(y^3 + (1/t)*y + t^3/(t+1))
     133            Function field in y defined by y^3 + 1/t*y + t^3/(t + 1)
     134
     135        The defining polynomial need not be monic or integral::
     136
     137            sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1))
     138            Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1)
     139        """
     140        if names is None:
     141            names = f.variable_name()
     142        return FunctionField_polymod(f, names)
     143
     144    def order_with_basis(self, basis, check=True):
     145        """
     146        Return the order with given basis over the maximal order of
     147        the base field.
     148
     149        INPUT:
     150
     151           - ``basis`` -- a list of elements of self
     152           - ``check`` -- bool (default: True); if True, check that
     153             the basis is really linearly independent
     154
     155        OUTPUT:
     156
     157            - an order in this function field
     158
     159        EXAMPLES::
     160
     161            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^3 + x^3 + 4*x + 1)
     162            sage: O = L.order_with_basis([1, Y, Y^2]); O
     163            Order in Function field in Y defined by y^3 + x^3 + 4*x + 1
     164            sage: O.basis()
     165            (1, Y, Y^2)
     166            sage: O = L.order_with_basis([x, x^2 + x*Y, (2/3)*Y^2]); O
     167            Order in Function field in Y defined by y^3 + x^3 + 4*x + 1
     168            sage: O.basis()
     169            (x, x*Y + x^2, 2/3*Y^2)
     170        """
     171        from function_field_order import FunctionFieldOrder_basis
     172        return FunctionFieldOrder_basis([self(a) for a in basis], check=check)
     173
     174    def order(self, x, check=True):
     175        """
     176        Return the order in this function field generated over the
     177        maximal order by x or the elements of x if x is a list.
     178
     179        INPUT:
     180       
     181           - ``x`` -- element of self, or a list of elements of self
     182           - ``check`` -- bool (default: True); if True, check that
     183             x really generates an order
     184
     185        EXAMPLES::
     186
     187            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^3 + x^3 + 4*x + 1)
     188            sage: O = L.order(Y); O
     189            Order in Function field in Y defined by y^3 + x^3 + 4*x + 1
     190            sage: O.basis()
     191            (1, Y, Y^2)
     192
     193            sage: Z = K.order(x); Z
     194            Order in Rational function field in x over Rational Field
     195            sage: Z.basis()
     196            (1,)
     197
     198        Orders with multiple generators, not yet supported::
     199
     200            sage: Z = K.order([x,x^2]); Z
     201            Traceback (most recent call last):
     202            ...
     203            NotImplementedError
     204        """
     205        if not isinstance(x, (list, tuple)):
     206            x = [x]
     207        if len(x) == 1:
     208            g = x[0]
     209            basis = [self(1)]
     210            for i in range(self.degree()-1):
     211                basis.append(basis[-1]*g)
     212        else:
     213            raise NotImplementedError
     214        return self.order_with_basis(basis, check=check)
     215
     216    def _coerce_map_from_(self, R):
     217        """
     218        Return True if there is a coerce map from R to self.
     219
     220        EXAMPLES::
     221
     222            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^3 + x^3 + 4*x + 1)
     223            sage: L.equation_order()
     224            Order in Function field in Y defined by y^3 + x^3 + 4*x + 1
     225            sage: L._coerce_map_from_(L.equation_order())
     226            True
     227            sage: L._coerce_map_from_(GF(7))
     228            False
     229        """
     230        from function_field_order import FunctionFieldOrder
     231        if isinstance(R, FunctionFieldOrder) and R.fraction_field() == self:
     232            return True
     233        return False
     234
     235    def hom(self, im_gens, base_morphism=None):
     236        """
     237        Create a homomorphism from self to another function field.
     238       
     239        INPUT:
     240
     241           - ``im_gens`` -- a list of images of the generators of self
     242             and of successive base rings.
     243           
     244           - ``base_morphism`` -- (default: None) a homomorphism of
     245             the base ring, after the im_gens are used.  Thus if
     246             im_gens has length 2, then base_morphism should be a morphism
     247             from self.base_ring().base_ring().
     248
     249        EXAMPLES::
     250       
     251        We create a rational function field, and a quadratic extension of it::
     252       
     253            sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     254            sage: L.<y> = R.extension(y^2 - x^3 - 1)
     255
     256        We make the field automorphism that sends y to -y::
     257       
     258            sage: f = L.hom(-y); f
     259            Morphism of function fields defined by y |--> -y
     260
     261        Evaluation works::
     262       
     263            sage: f(y*x - 1/x)
     264            -x*y - 1/x
     265
     266        We try to define an invalid morphism::
     267       
     268            sage: f = L.hom(y+1); f
     269            Traceback (most recent call last):
     270            ...
     271            ValueError: invalid morphism
     272
     273        We make a morphism of the base rational function field::
     274       
     275            sage: phi = R.hom(x+1); phi
     276            Morphism of function fields defined by x |--> x + 1
     277            sage: phi(x^3 - 3)
     278            x^3 + 3*x^2 + 3*x - 2
     279            sage: (x+1)^3-3
     280            x^3 + 3*x^2 + 3*x - 2
     281
     282        We make a morphism by specifying where the generators and the
     283        base generators go::
     284       
     285            sage: L.hom([-y, x])
     286            Morphism of function fields defined by y |--> -y,  x |--> x
     287
     288        We make another extension of a rational function field::
     289       
     290            sage: R2.<t> = FunctionField(QQ); S2.<w> = R2[]
     291            sage: L2.<w> = R.extension((4*w)^2 - (t+1)^3 - 1)
     292
     293        We define a morphism, by givin the images of generators::
     294       
     295            sage: f = L.hom([4*w, t+1]); f
     296            Morphism of function fields defined by y |--> 4*w,  x |--> t + 1
     297
     298        Evaluation works, as expected::
     299       
     300            sage: f(y+x)
     301            4*w + t + 1
     302            sage: f(x*y + x/(x^2+1))
     303            (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2)
     304        """
     305        if not isinstance(im_gens, (list,tuple)):
     306            im_gens = [im_gens]
     307        if len(im_gens) > 1:
     308            base_morphism = self.base_field().hom(im_gens[1:], base_morphism)
     309        return maps.FunctionFieldMorphism(self.Hom(im_gens[0].parent()), im_gens[0], base_morphism)
     310
     311class FunctionField_polymod(FunctionField):
     312    """
     313    A function field defined by a univariate polynomial, as an
     314    extension of the base field.
     315   
     316    EXAMPLES::
     317
     318    We make a function field defined by a degree 5 polynomial over the
     319    rational function field over the rational numbers::
     320   
     321        sage: K.<x> = FunctionField(QQ)
     322        sage: R.<y> = K[]
     323        sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     324        Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     325
     326    We next make a function field over the above nontrivial function
     327    field L::
     328
     329        sage: S.<T> = L[]
     330        sage: M.<alpha> = L.extension(T^2 + w*T + y); M
     331        Function field in alpha defined by T^2 + w*T + w
     332        sage: 1/alpha
     333        ((x/(-x^4 - 1))*w^4 - 2*x^2/(-x^4 - 1))*alpha - 1
     334        sage: alpha * (1/alpha)
     335        1
     336
     337    We drill down the tower of function fields::
     338   
     339        sage: M.base_field()
     340        Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     341        sage: M.base_field().base_field()
     342        Rational function field in x over Rational Field
     343        sage: M.base_field().base_field().constant_field()
     344        Rational Field
     345        sage: M.constant_base_field()
     346        Rational Field
     347    """
     348    def __init__(self, polynomial, names, category=CAT):
     349        """
     350        Create a function field defined as an extension of another
     351        function field by adjoining a root of a univariate polynomial.
     352
     353        INPUT:
     354
     355            - ``polynomial`` -- a univariate polynomial over a function field
     356            - ``names`` -- variable names (as a tuple of length 1 or string)
     357            - ``category`` -- a category (defaults to category of function fields)
     358       
     359        EXAMPLES::
     360
     361        We create an extension of function fields::
     362       
     363            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     364            sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L
     365            Function field in y defined by y^5 + x*y - x^3 - 3*x
     366
     367        Note the type::
     368       
     369            sage: type(L)
     370            <class 'sage.rings.function_field.function_field.FunctionField_polymod_with_category'>
     371
     372        We can set the variable name, which doesn't have to be y::
     373       
     374            sage: L.<w> = K.extension(y^5 - x^3 - 3*x + x*y); L
     375            Function field in w defined by y^5 + x*y - x^3 - 3*x
     376        """
     377        from sage.rings.polynomial.all import is_Polynomial
     378        if names is None:
     379            names = (polynomial.variable_name(), )
     380        if not is_Polynomial(polynomial):
     381            raise TypeError, "polynomial must be a polynomial"
     382        if polynomial.degree() <= 0:
     383            raise ValueError, "polynomial must have positive degree"
     384        base_field = polynomial.base_ring()
     385        if not isinstance(base_field, FunctionField):
     386            raise TypeError, "polynomial must be over a function"
     387        self._base_field = base_field
     388        self._polynomial = polynomial
     389       
     390        ParentWithGens.__init__(self, base_field,
     391                                names=names, category = category)
     392
     393        self._hash = hash(polynomial)
     394        self._ring = self._polynomial.parent()
     395        self._populate_coercion_lists_(coerce_list=[base_field, self._ring])
     396        self._gen = self(self._ring.gen())
     397
     398    def __hash__(self):
     399        """
     400        Return hash of this function field.
     401       
     402        EXAMPLES::
     403
     404            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     405            sage: L = K.extension(y^5 - x^3 - 3*x + x*y); hash(L)
     406            3183366741743088279             # 64-bit
     407            ?                               # 32-bit
     408
     409        """
     410        return self._hash
     411
     412    def monic_integral_model(self, names):
     413        """
     414        Return a function field isomorphic to self, but with defining
     415        polynomial that is monic and integral over the base field.
     416
     417        INPUT::
     418
     419            - ``names`` -- name of the generator of the new field this function constructs
     420
     421        EXAMPLES::
     422
     423            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     424            sage: L.<alpha> = K.extension(x^2*y^5 - 1/x); L
     425            Function field in alpha defined by x^2*y^5 - 1/x
     426            sage: A, from_A, to_A = L.monic_integral_model('beta')
     427            sage: A
     428            Function field in beta defined by y^5 - x^12
     429            sage: from_A
     430            Morphism of function fields defined by beta |--> x^3*alpha
     431            sage: to_A
     432            Morphism of function fields defined by alpha |--> 1/x^3*beta
     433            sage: to_A(alpha)
     434            1/x^3*beta
     435            sage: from_A(to_A(alpha))
     436            alpha
     437            sage: from_A(to_A(1/alpha))
     438            x^3*alpha^4
     439            sage: from_A(to_A(1/alpha)) == 1/alpha
     440            True           
     441        """
     442        g, d = self._make_monic(self.polynomial())
     443        R = self.base_field()
     444        K = R.extension(g, names=names)
     445        to_K = self.hom(K.gen() / d)
     446        from_K = K.hom(self.gen() * d)
     447        return K, from_K, to_K
     448
     449    def _make_monic(self, f):
     450        r"""
     451        Let alpha be a root of f.  This function returns a monic
     452        integral polynomial g and an element d of the base field such
     453        that g(alpha*d) = 0.
     454       
     455        EXAMPLES::
     456       
     457            sage: K.<x> = FunctionField(QQ); R.<y> = K[];
     458            sage: L.<alpha> = K.extension(x^2*y^5 - 1/x)
     459            sage: g, d = L._make_monic(L.polynomial()); g,d
     460            (y^5 - x^12, x^3)
     461            sage: g(alpha*d)
     462            0
     463        """
     464        R = f.base_ring()
     465        if not isinstance(R, RationalFunctionField):
     466            raise NotImplementedError
     467       
     468        # make f monic
     469        n = f.degree()
     470        c = f.leading_coefficient()
     471        if c != 1:
     472            f = f / c
     473
     474        # find lcm of denominators
     475        from sage.rings.arith import lcm
     476        # would be good to replace this by minimal...
     477        d = lcm([b.denominator() for b in f.list() if b])
     478        if d != 1:
     479            x = f.parent().gen()
     480            g = (d**n) * f(x/d)
     481        else:
     482            g = f
     483        return g, d
     484
     485    def constant_field(self):
     486        """
     487        Return the algebraic closure of the constant field of the base
     488        field in this function field.
     489
     490        EXAMPLES::
     491
     492            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     493            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     494            sage: L.constant_field()
     495            Traceback (most recent call last):
     496            ...
     497            NotImplementedError
     498        """
     499        raise NotImplementedError
     500
     501    def constant_base_field(self):
     502        """
     503        Return the constant field of the base rational function field.
     504               
     505        EXAMPLES::
     506
     507            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     508            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     509            Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     510            sage: L.constant_base_field()
     511            Rational Field
     512        """
     513        return self.base_field().constant_base_field()
     514
     515    def degree(self):
     516        """
     517        Return the degree of this function field over its base
     518        function field.
     519       
     520        EXAMPLES::
     521
     522            sage: K.<x> = FunctionField(QQ)
     523            sage: R.<y> = K[]
     524            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     525            Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     526            sage: L.degree()
     527            5       
     528        """
     529        return self._polynomial.degree()
     530       
     531    def _repr_(self):
     532        """
     533        Return string representation of this function field.
     534       
     535        EXAMPLES::
     536
     537            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     538            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     539            sage: L._repr_()
     540            'Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x'
     541        """
     542        return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial)
     543
     544    def base_field(self):
     545        """
     546        Return the base field of this function field.  This function
     547        field is presented as L = K[y]/(f(y)), and the base field is
     548        by definition the field K.
     549       
     550        EXAMPLES::
     551            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     552            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     553            sage: L.base_field()
     554            Rational function field in x over Rational Field
     555        """
     556        return self._base_field
     557
     558    def random_element(self, *args, **kwds):
     559        """
     560        Create a random element of this function field.  Parameters
     561        are passed onto the random_element method of the base_field.
     562
     563        EXAMPLES::
     564
     565            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     566            sage: L.<w> = K.extension(y^2 - (x^2 + x))
     567            sage: L.random_element()
     568            ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*w^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*w + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95)
     569        """
     570        return self(self._ring.random_element(degree=self.degree(), *args, **kwds))
     571
     572    def polynomial(self):
     573        """
     574        Return the univariate polynomial that defines this function
     575        field, i.e., the polynomial f(y) so that this function field
     576        is of the form K[y]/(f(y)).
     577       
     578        EXAMPLES::
     579
     580            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     581            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     582            sage: L.polynomial()
     583            y^5 - 2*x*y + (-x^4 - 1)/x
     584        """
     585        return self._polynomial
     586
     587    def polynomial_ring(self):
     588        """
     589        Return the polynomial ring used to represents elements of this
     590        function field.  If we view this function field as being presented
     591        as K[y]/(f(y)), then this function returns the ring K[y].
     592       
     593        EXAMPLES::
     594
     595            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     596            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     597            sage: L.polynomial_ring()
     598            Univariate Polynomial Ring in y over Rational function field in x over Rational Field
     599        """
     600        return self._ring
     601
     602    def vector_space(self):
     603        """
     604        Return a vector space V and isomorphisms self --> V and V --> self.
     605
     606        This function allows us to identify the elements of self with
     607        elements of a vector space over the base field, which is
     608        useful for representation and arithmetic with orders, ideals,
     609        etc.
     610       
     611        OUTPUT:
     612
     613            -  ``V`` - a vector space over the rational numbers
     614            -  ``from_V`` - an isomorphism from V to self
     615            -  ``to_V`` - an isomorphism from self to V
     616
     617        EXAMPLES::
     618
     619        We define a function field::
     620       
     621            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     622            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     623            Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     624
     625        We get the vector spaces, and maps back and forth::
     626       
     627            sage: V, from_V, to_V = L.vector_space()
     628            sage: V
     629            Vector space of dimension 5 over Rational function field in x over Rational Field
     630            sage: from_V
     631            Isomorphism map:
     632              From: Vector space of dimension 5 over Rational function field in x over Rational Field
     633              To:   Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     634            sage: to_V
     635            Isomorphism map:
     636              From: Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     637              To:   Vector space of dimension 5 over Rational function field in x over Rational Field
     638
     639        We convert an element of the vector space back to the function field::
     640       
     641            sage: from_V(V.1)
     642            w
     643
     644        We define an interesting element of the function field::
     645       
     646            sage: a = 1/L.0; a
     647            (-x/(-x^4 - 1))*w^4 + 2*x^2/(-x^4 - 1)
     648
     649        We convert it to the vector space, and get a vector over the base field::
     650       
     651            sage: to_V(a)
     652            (2*x^2/(-x^4 - 1), 0, 0, 0, -x/(-x^4 - 1))
     653
     654        We convert to and back, and get the same element::
     655       
     656            sage: from_V(to_V(a)) == a
     657            True
     658
     659        In the other direction::
     660
     661            sage: v = x*V.0 + (1/x)*V.1
     662            sage: to_V(from_V(v)) == v
     663            True
     664        """
     665        try: return self._vector_space
     666        except AttributeError:
     667            V = self.base_field()**self.degree()
     668            from_V = maps.MapVectorSpaceToFunctionField(V, self)
     669            to_V   = maps.MapFunctionFieldToVectorSpace(self, V)
     670            self._vector_space = (V, from_V, to_V)
     671            return self._vector_space
     672       
     673
     674    def maximal_order(self):
     675        """
     676        Return the maximal_order of self.  If we view self as L =
     677        K[y]/(f(y)), then this is the ring of elements of L that are
     678        integral over K.
     679       
     680        EXAMPLES::
     681
     682        This is not yet implemented...::
     683       
     684            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     685            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     686            sage: L.maximal_order()
     687            Traceback (most recent call last):
     688            ...
     689            NotImplementedError
     690        """
     691        raise NotImplementedError
     692
     693    def _element_constructor_(self, x):
     694        r"""
     695        Make x into an element of this function field, possibly not canonically.
     696
     697        INPUT:
     698       
     699            - ``x`` - the element
     700         
     701        OUTPUT:
     702       
     703            ``x``, as an element of this function field
     704
     705        TESTS::
     706
     707            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     708            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     709            sage: L._element_constructor_(L.polynomial_ring().gen())
     710            w
     711        """
     712        if x.parent() is self._ring:
     713            return function_field_element.FunctionFieldElement_polymod(self, x)
     714        if isinstance(x, function_field_element.FunctionFieldElement):
     715            return function_field_element.FunctionFieldElement_polymod(self, self._ring(x.element()))           
     716        return function_field_element.FunctionFieldElement_polymod(self, self._ring(x))
     717   
     718
     719    def gen(self, n=0):
     720        """
     721        Return the n-th generator of this function field.  By default n=0; any other
     722        value of n leads to an error.   The generator is the class of y, if we view
     723        self as being presented as K[y]/(f(y)).
     724       
     725        EXAMPLES::
     726
     727            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     728            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     729            sage: L.gen()
     730            w
     731            sage: L.gen(1)
     732            Traceback (most recent call last):
     733            ...
     734            IndexError: Only one generator.
     735        """
     736        if n != 0: raise IndexError, "Only one generator."
     737        return self._gen
     738
     739    def ngens(self):
     740        """
     741        Return the number of generators of this function field over
     742        its base field.  This is by definition 1.
     743       
     744        EXAMPLES::
     745       
     746            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     747            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     748            sage: L.ngens()
     749            1
     750        """
     751        return 1
     752
     753    def equation_order(self):
     754        """
     755        If we view self as being presented as K[y]/(f(y)), then this
     756        function returns the order generated by the class of y.  If f
     757        is not monic, then self._make_monic is called, and instead we
     758        get the order generated by some integral multiple of a root of
     759        alpha.
     760       
     761        EXAMPLES::
     762
     763            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     764            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     765            sage: L.equation_order()
     766            Order in Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     767
     768        We try an example, in which the defining polynomial is not
     769        monic and is not integral::
     770
     771            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     772            sage: L.<alpha> = K.extension(x^2*y^5 - 1/x); L
     773            Function field in alpha defined by x^2*y^5 - 1/x
     774            sage: O = L.equation_order(); O
     775            Order in Function field in alpha defined by x^2*y^5 - 1/x
     776            sage: O.basis()
     777            (1, x^3*alpha, x^6*alpha^2, x^9*alpha^3, x^12*alpha^4)
     778        """
     779        d = self._make_monic(self.polynomial())[1]
     780        return self.order(d*self.gen(), check=False)
     781   
     782
     783class RationalFunctionField(FunctionField):
     784    """
     785    A rational function field K(t) in one variable, over an arbitrary
     786    base field.
     787   
     788    EXAMPLES::
     789
     790        sage: K.<t> = FunctionField(GF(3)); K
     791        Rational function field in t over Finite Field of size 3
     792        sage: K.gen()
     793        t
     794        sage: 1/t + t^3 + 5
     795        (t^4 + 2*t + 1)/t
     796
     797    There are various ways to get at the underlying fields and rings
     798    associated to a rational function field::
     799
     800        sage: K.<t> = FunctionField(GF(7))
     801        sage: K.base_field()
     802        Rational function field in t over Finite Field of size 7
     803        sage: K.field()
     804        Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     805        sage: K.constant_field()
     806        Finite Field of size 7
     807        sage: K.maximal_order()
     808        Maximal order in Rational function field in t over Finite Field of size 7
     809
     810    We define a morphism::
     811
     812        sage: K.<W> = FunctionField(QQ)
     813        sage: L = FunctionField(QQ, 'tbar')         # give var name as second input
     814        sage: K.hom(L.gen())
     815        Morphism of function fields defined by W |--> tbar
     816    """
     817    def __init__(self, constant_field, names, category=CAT):
     818        """
     819        Create a rational function field in one variable.
     820
     821        INPUT:
     822
     823            - ``constant_field`` -- an arbitrary field
     824            - ``names`` -- a string or tuple of length 1
     825            - ``category`` -- default: FunctionFields()
     826       
     827        EXAMPLES::
     828
     829            sage: K.<t> = FunctionField(CC); K
     830            Rational function field in t over Complex Field with 53 bits of precision
     831            sage: K.category()
     832            Category of function fields
     833            sage: FunctionField(QQ[I], 'alpha')
     834            Rational function field in alpha over Number Field in I with defining polynomial x^2 + 1
     835
     836        Must be over a field::
     837       
     838            sage: FunctionField(ZZ, 't')
     839            Traceback (most recent call last):
     840            ...
     841            TypeError: constant_field must be a field
     842        """
     843        if names is None:
     844            raise ValueError, "variable name must be specified"
     845        elif not isinstance(names, tuple):
     846            names = (names, )
     847        if not constant_field.is_field():
     848            raise TypeError, "constant_field must be a field"
     849        ParentWithGens.__init__(self, self, names=names, category = category)
     850        R = constant_field[names[0]]
     851        self._hash = hash((constant_field, names))
     852        self._constant_field = constant_field
     853        self._ring = R
     854        self._field = R.fraction_field()
     855        self._populate_coercion_lists_(coerce_list=[self._field])
     856        self._gen = self(R.gen())
     857
     858    def __hash__(self):
     859        """
     860        Return hash of this function field.
     861
     862        EXAMPLES::
     863       
     864            sage: K.<t> = FunctionField(QQ)
     865            sage: hash(K)
     866            502145503910697533              # 64-bit
     867            ?                               # 32-bit           
     868        """
     869        return self._hash
     870
     871    def _repr_(self):
     872        """
     873        Return string representation of this function field.
     874       
     875        EXAMPLES::
     876       
     877            sage: K.<t> = FunctionField(QQ)
     878            sage: K._repr_()
     879            'Rational function field in t over Rational Field'
     880        """
     881        return "Rational function field in %s over %s"%(
     882            self.variable_name(), self._constant_field)
     883
     884    def _element_constructor_(self, x):
     885        r"""
     886        Coerce x into an element of this function field, possibly not canonically.
     887
     888        INPUT:
     889       
     890            - ``x`` - the element
     891         
     892        OUTPUT:
     893       
     894            ``x``, as an element of this function field
     895
     896        EXAMPLES::
     897       
     898            sage: K.<t> = FunctionField(QQ)
     899            sage: a = K._element_constructor_(K.maximal_order().gen()); a
     900            t
     901            sage: a.parent()
     902            Rational function field in t over Rational Field
     903        """
     904        if x.parent() is self._field:
     905            return function_field_element.FunctionFieldElement_rational(self, x)
     906        if isinstance(x, function_field_element.FunctionFieldElement):
     907            return function_field_element.FunctionFieldElement_rational(self, self._field(x.element()))
     908        if x.parent() is self.polynomial_ring():
     909            return x[0]
     910        return function_field_element.FunctionFieldElement_rational(self, self._field(x))
     911
     912    # nonoptimized
     913    def _to_bivariate_polynomial(self, f):
     914        """
     915        Convert f from a univariate polynomial over the rational function
     916        field into a bivariate polynomial and a denominator.
     917
     918        INPUT:
     919
     920            - f -- a univariate polynomial over self.
     921
     922        OUTPUT:
     923
     924            - 2-variate polynomial, denominator
     925
     926        EXAMPLES::
     927       
     928            sage: R.<t> = FunctionField(GF(7))
     929            sage: S.<X> = R[]
     930            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     931            sage: R._to_bivariate_polynomial(f)
     932            (x^7*t^2 - x^4*t^5 - x^3 + t^3, t^3)       
     933        """
     934        v = f.list()
     935        from sage.rings.arith import LCM
     936        denom = LCM([a.denominator() for a in v])
     937        S = denom.parent()
     938        x,t = S.base_ring()['x,t'].gens()
     939        phi = S.hom([t])
     940        return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom
     941
     942    def _factor_univariate_polynomial(self, f, proof=True):
     943        """
     944        Factor the univariate polynomial f over self.
     945
     946        EXAMPLES::
     947
     948        We do a factorization over the function field over the rationals::
     949
     950            sage: R.<t> = FunctionField(QQ)
     951            sage: S.<X> = R[]
     952            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     953            sage: f.factor()             # indirect doctest
     954            (1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2)
     955            sage: f.factor().prod() == f
     956            True       
     957
     958        You must pass in proof=False over finite fields, due to
     959        Singular's factoring algorithm being incomplete::
     960
     961            sage: R.<t> = FunctionField(GF(7))
     962            sage: S.<X> = R[]
     963            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     964            sage: f.factor()
     965            Traceback (most recent call last):
     966            ...
     967            NotImplementedError: proof = True factorization not implemented.  Call factor with proof=False.
     968            sage: f.factor(proof=False)
     969            (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t)
     970            sage: f.factor(proof=False).prod() == f
     971            True
     972
     973        Factoring over a function field over a non-prime finite field::
     974
     975            sage: k.<a> = GF(9)
     976            sage: R.<t> = FunctionField(k)
     977            sage: S.<X> = R[]
     978            sage: f = (1/t)*(X^3 - a*t^3)
     979            sage: f.factor(proof=False)
     980            (1/t) * (X + (a + 2)*t)^3
     981            sage: f.factor(proof=False).prod() == f
     982            True
     983        """
     984        F, d = self._to_bivariate_polynomial(f)
     985        fac = F.factor(proof=proof)
     986        x = f.parent().gen()
     987        t = f.parent().base_ring().gen()
     988        phi = F.parent().hom([x, t])
     989        v = [(phi(P),e) for P, e in fac]
     990        unit = phi(fac.unit())/d
     991        w = []
     992        for a, e in v:
     993            c = a.leading_coefficient()
     994            a = a/c
     995            unit *= (c**e)
     996            w.append((a,e))
     997        from sage.structure.factorization import Factorization
     998        return Factorization(w, unit=unit)
     999
     1000    def polynomial_ring(self, var='x'):
     1001        """
     1002        Return polynomial ring K[var] that could be used to represent
     1003        elements of self, if self were viewed as K[var]/(var).
     1004       
     1005        EXAMPLES::
     1006       
     1007            sage: K.<x> = FunctionField(QQ)
     1008            sage: K.polynomial_ring()
     1009            Univariate Polynomial Ring in x over Rational function field in x over Rational Field
     1010            sage: K.polynomial_ring('T')
     1011            Univariate Polynomial Ring in T over Rational function field in x over Rational Field
     1012        """
     1013        if var != 'x': return self[var]
     1014        try: return self._polynomial_ring
     1015        except AttributeError:
     1016            self._polynomial_ring = self[var]
     1017            return self._polynomial_ring
     1018
     1019    def vector_space(self):
     1020        """
     1021        Return a vector space V and isomorphisms self --> V and V --> self.
     1022       
     1023        OUTPUT:
     1024
     1025            -  ``V`` - a vector space over the rational numbers
     1026            -  ``from_V`` - an isomorphism from V to self
     1027            -  ``to_V`` - an isomorphism from self to V
     1028
     1029        EXAMPLES::
     1030
     1031            sage: K.<x> = FunctionField(QQ)
     1032            sage: K.vector_space()
     1033            (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism map:
     1034              From: Vector space of dimension 1 over Rational function field in x over Rational Field
     1035              To:   Rational function field in x over Rational Field, Isomorphism map:
     1036              From: Rational function field in x over Rational Field
     1037              To:   Vector space of dimension 1 over Rational function field in x over Rational Field)
     1038        """
     1039        try: return self._vector_space
     1040        except AttributeError:
     1041            V = self.base_field()**1
     1042            from_V = maps.MapVectorSpaceToFunctionField(V, self)
     1043            to_V   = maps.MapFunctionFieldToVectorSpace(self, V)
     1044            self._vector_space = (V, from_V, to_V)
     1045            return self._vector_space
     1046
     1047    def random_element(self, *args, **kwds):
     1048        """
     1049        Create a random element of this rational function field.
     1050        Parameters are passed onto the random_element method of the
     1051        underlying fraction field.
     1052
     1053        EXAMPLES::
     1054
     1055            sage: FunctionField(QQ,'alpha').random_element()
     1056            (-1/2*alpha^2 - 4)/(-12*alpha^2 + 1/2*alpha - 1/95)
     1057        """
     1058        return self(self._field.random_element(*args, **kwds))
     1059
     1060    def degree(self):
     1061        """
     1062        Return the degree over the base field of this rational
     1063        function field, which is 1.
     1064       
     1065        EXAMPLES::
     1066       
     1067            sage: K.<t> = FunctionField(QQ)
     1068            sage: K.degree()
     1069            1
     1070        """
     1071        return ZZ(1)
     1072   
     1073    def gen(self, n=0):
     1074        """
     1075        Return the n-th generator of this function field.  If n is not
     1076        0, then an IndexError is raised.
     1077
     1078        EXAMPLES::
     1079           
     1080            sage: K.<t> = FunctionField(QQ); K.gen()
     1081            t
     1082            sage: K.gen().parent()
     1083            Rational function field in t over Rational Field
     1084            sage: K.gen(1)
     1085            Traceback (most recent call last):
     1086            ...
     1087            IndexError: Only one generator.
     1088        """
     1089        if n != 0:
     1090            raise IndexError, "Only one generator."
     1091        return self._gen
     1092
     1093    def ngens(self):
     1094        """
     1095        Return the number of generators, which is 1.
     1096       
     1097        EXAMPLES::
     1098
     1099            sage: K.<t> = FunctionField(QQ)
     1100            sage: K.ngens()
     1101            1
     1102        """
     1103        return 1
     1104   
     1105    def base_field(self):
     1106        """
     1107        Return the base field of this rational function field, which is just
     1108        this function field itself.
     1109       
     1110        EXAMPLES::
     1111       
     1112            sage: K.<t> = FunctionField(GF(7))
     1113            sage: K.base_field()
     1114            Rational function field in t over Finite Field of size 7
     1115        """
     1116        return self
     1117
     1118    def hom(self, im_gens, base_morphism=None):
     1119        """
     1120        Create a homomorphism from self to another function field.
     1121
     1122        INPUT:
     1123
     1124            - ``im_gens`` -- exactly one element of some function field
     1125            - ``base_morphism`` -- ignored
     1126
     1127        OUTPUT:
     1128
     1129            - a map between function fields
     1130
     1131        EXAMPLES::
     1132
     1133        We make a map from a rational function field to itself::
     1134
     1135            sage: R.<x> = FunctionField(GF(7))
     1136            sage: R.hom( (x^4 + 2)/x)
     1137            Morphism of function fields defined by x |--> (x^4 + 2)/x       
     1138       
     1139        We construct a map from a rational function field into a
     1140        non-rational extension field::
     1141       
     1142            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     1143            sage: L.<y> = R.extension(y^3 + 6*x^3 + x)
     1144            sage: f = R.hom(y^2 + y  + 2); f
     1145            Morphism of function fields defined by x |--> y^2 + y + 2
     1146            sage: f(x)
     1147            y^2 + y + 2
     1148            sage: f(x^2)
     1149            5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4       
     1150        """
     1151        if isinstance(im_gens, CategoryObject):
     1152            return self.Hom(im_gens).natural_map()
     1153        if not isinstance(im_gens, (list,tuple)):
     1154            im_gens = [im_gens]
     1155        if len(im_gens) != 1:
     1156            raise ValueError, "there must be exactly one generator"
     1157        x = im_gens[0]
     1158        return maps.FunctionFieldMorphism_rational(self.Hom(x.parent()), x)
     1159
     1160    def field(self):
     1161        """
     1162        Return the underlying field, forgetting the function field
     1163        structure.
     1164       
     1165        EXAMPLES::
     1166
     1167            sage: K.<t> = FunctionField(GF(7))
     1168            sage: K.field()
     1169            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1170        """
     1171        return self._field
     1172
     1173    def maximal_order(self):
     1174        """
     1175        Return the maximal order of this function field.  Since this
     1176        is a rational function field it is of the form K(t), and the
     1177        maximal order is by definition K[t].
     1178       
     1179        EXAMPLES::
     1180       
     1181            sage: K.<t> = FunctionField(QQ)
     1182            sage: K.maximal_order()
     1183            Maximal order in Rational function field in t over Rational Field
     1184            sage: K.equation_order()
     1185            Maximal order in Rational function field in t over Rational Field
     1186        """
     1187        try: return self._maximal_order
     1188        except AttributeError:
     1189            from function_field_order import FunctionFieldOrder_rational
     1190            self._maximal_order = FunctionFieldOrder_rational(self)
     1191            return self._maximal_order
     1192
     1193    equation_order = maximal_order
     1194
     1195    def constant_base_field(self):
     1196        """
     1197        Return the field that this rational function field is a
     1198        transcendental extension of.
     1199
     1200        EXAMPLES::
     1201
     1202            sage: K.<t> = FunctionField(QQ)
     1203            sage: K.constant_field()
     1204            Rational Field
     1205        """
     1206        return self._constant_field
     1207
     1208    constant_field = constant_base_field
     1209
     1210
     1211       
     1212
     1213   
     1214
     1215
  • new file sage/rings/function_field/function_field_element.pyx

    diff --git a/sage/rings/function_field/function_field_element.pyx b/sage/rings/function_field/function_field_element.pyx
    new file mode 100644
    - +  
     1include "../../ext/stdsage.pxi"
     2
     3from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element
     4
     5def is_FunctionFieldElement(x):
     6    """
     7    Return True if x is any type of function field element.
     8   
     9    EXAMPLES::
     10
     11        sage: t = FunctionField(QQ,'t').gen()
     12        sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(t)
     13        True
     14        sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(0)
     15        False
     16    """
     17    return isinstance(x, FunctionFieldElement)
     18
     19cdef class FunctionFieldElement(FieldElement):
     20
     21    cdef readonly object _x
     22    cdef readonly object _matrix
     23   
     24    """
     25    The abstract base class for function field elements.
     26   
     27    EXAMPLES::
     28
     29        sage: t = FunctionField(QQ,'t').gen()
     30        sage: isinstance(t, sage.rings.function_field.function_field_element.FunctionFieldElement)
     31        True
     32    """
     33
     34    cdef FunctionFieldElement _new_c(self):
     35        cdef FunctionFieldElement x = <FunctionFieldElement>PY_NEW_SAME_TYPE(self)
     36        x._parent = self._parent
     37        return x
     38   
     39    def _latex_(self):
     40        """
     41        EXAMPLES::
     42       
     43            sage: K.<t> = FunctionField(QQ)
     44            sage: latex((t+1)/t)
     45            \frac{t + 1}{t}
     46            sage: latex((t+1)/t^67)
     47            \frac{t + 1}{t^{67}}
     48            sage: latex((t+1/2)/t^67)
     49            \frac{t + \frac{1}{2}}{t^{67}}
     50        """
     51        return self._x._latex_()
     52   
     53    def matrix(self):
     54        r"""
     55        Return the matrix of multiplication by self.
     56
     57        EXAMPLES::
     58
     59        A rational function field:
     60       
     61            sage: K.<t> = FunctionField(QQ)
     62            sage: t.matrix()
     63            [t]
     64            sage: (1/(t+1)).matrix()
     65            [1/(t + 1)]
     66
     67        Now an example in a nontrivial extension of a rational function field::
     68       
     69            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     70            sage: Y.matrix()
     71            [     0      1]
     72            [-4*x^3      x]
     73            sage: Y.matrix().charpoly('Z')
     74            Z^2 - x*Z + 4*x^3
     75
     76        An example in a relative extension, where neither function
     77        field is rational::
     78
     79            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     80            sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
     81            sage: alpha.matrix()
     82            [          0           1           0]
     83            [          0           0           1]
     84            [         -x x*Y - 4*x^3           0]
     85        """
     86        if self._matrix is None:
     87            # Multiply each power of field generator on the left by this
     88            # element; make matrix whose rows are the coefficients of the
     89            # result, and transpose.
     90            K = self.parent()
     91            v = []
     92            x = K.gen()
     93            a = K(1)
     94            d = K.degree()
     95            for n in range(d):
     96                v += (a*self).list()
     97                a *= x
     98            k = K.base_ring()
     99            import sage.matrix.matrix_space
     100            M = sage.matrix.matrix_space.MatrixSpace(k, d)
     101            self._matrix = M(v)
     102        return self._matrix
     103
     104    def trace(self):
     105        """
     106        Return the trace of this function field element.
     107
     108        EXAMPLES::
     109
     110            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     111            sage: Y.trace()
     112            x
     113        """
     114        return self.matrix().trace()
     115
     116    def norm(self):
     117        """
     118        Return the norm of this function field element.
     119
     120        EXAMPLES::
     121       
     122            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     123            sage: Y.norm()
     124            4*x^3
     125
     126
     127        The norm is relative::
     128       
     129            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     130            sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
     131            sage: alpha.norm()
     132            -x
     133            sage: alpha.norm().parent()
     134            Function field in Y defined by y^2 - x*y + 4*x^3
     135        """
     136        return self.matrix().determinant()
     137
     138    def characteristic_polynomial(self, *args, **kwds):
     139        """
     140        Return the characteristic polynomial of this function field
     141        element.  Give an optional input string to name the variable
     142        in the characteristic polynomial.
     143
     144        EXAMPLES::
     145
     146            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     147            sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
     148            sage: x.characteristic_polynomial('W')
     149            W - x
     150            sage: Y.characteristic_polynomial('W')
     151            W^2 - x*W + 4*x^3
     152            sage: alpha.characteristic_polynomial('W')
     153            W^3 + (-x*Y + 4*x^3)*W + x
     154        """
     155        return self.matrix().characteristic_polynomial(*args, **kwds)
     156
     157    charpoly = characteristic_polynomial
     158
     159    def minimal_polynomial(self, *args, **kwds):
     160        """
     161        Return the minimal polynomial of this function field element.
     162        Give an optional input string to name the variable in the
     163        characteristic polynomial.
     164
     165        EXAMPLES::
     166
     167            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     168            sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
     169            sage: x.minimal_polynomial('W')
     170            W - x
     171            sage: Y.minimal_polynomial('W')
     172            W^2 - x*W + 4*x^3
     173            sage: alpha.minimal_polynomial('W')
     174            W^3 + (-x*Y + 4*x^3)*W + x
     175        """
     176        return self.matrix().minimal_polynomial(*args, **kwds)
     177
     178    minpoly = minimal_polynomial
     179   
     180    def is_integral(self):
     181        r"""
     182        Determine if self is integral over the maximal order of the base field.
     183       
     184        EXAMPLES::
     185       
     186            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     187            sage: Y.is_integral()
     188            True
     189            sage: (Y/x).is_integral()
     190            True
     191            sage: (Y/x)^2 - (Y/x) + 4*x
     192            0
     193            sage: (Y/x^2).is_integral()
     194            False
     195            sage: f = (Y/x).minimal_polynomial('W'); f
     196            W^2 - W + 4*x           
     197        """
     198        R = self.parent().base_field().maximal_order()
     199        return all([a in R for a in self.minimal_polynomial()])
     200
     201cdef class FunctionFieldElement_polymod(FunctionFieldElement):
     202    """
     203    EXAMPLES::
     204
     205        sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     206        sage: x*Y + 1/x^3
     207        x*Y + 1/x^3       
     208    """
     209    def __init__(self, parent, x):
     210        """
     211        EXAMPLES::
     212
     213             sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     214             sage: type(Y)
     215             <type 'sage.rings.function_field.function_field_element.FunctionFieldElement_polymod'>             
     216        """
     217        FieldElement.__init__(self, parent)
     218        self._x = x
     219
     220    def element(self):
     221        """
     222        Return the underlying polynomial that represents this element.
     223       
     224        EXAMPLES::
     225            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     226            sage: f = Y/x^2 + x/(x^2+1); f
     227            1/x^2*Y + x/(x^2 + 1)
     228            sage: f.element()
     229            1/x^2*y + x/(x^2 + 1)
     230            sage: type(f.element())
     231            <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>       
     232        """
     233        return self._x
     234
     235    def _repr_(self):
     236        """
     237        EXAMPLES::
     238
     239            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     240            sage: Y._repr_()
     241            'Y'
     242        """
     243        return self._x._repr(name=self.parent().variable_name())
     244       
     245    def __nonzero__(self):
     246        """
     247        EXAMPLES::
     248
     249            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     250            sage: bool(Y)
     251            True
     252            sage: bool(L(0))
     253            False
     254        """
     255        return not not self._x
     256
     257    cdef int _cmp_c_impl(self, Element other) except -2:
     258        """
     259        EXAMPLES::
     260
     261            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     262            sage: cmp(L, 0)
     263            1
     264            sage: cmp(0, L)
     265            -1
     266        """
     267        cdef int c = cmp(type(self), type(other))
     268        if c: return c
     269        cdef FunctionFieldElement left = <FunctionFieldElement>self
     270        cdef FunctionFieldElement right = <FunctionFieldElement>other
     271        c = cmp(left._parent, right._parent)
     272        return c or cmp(left._x, right._x)
     273
     274    cpdef ModuleElement _add_(self, ModuleElement right):
     275        """
     276        EXAMPLES::
     277
     278            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     279            sage: (2*Y + x/(1+x^3))  +  (3*Y + 5*x*Y)         # indirect doctest
     280            (5*x + 5)*Y + x/(x^3 + 1)
     281        """
     282        cdef FunctionFieldElement res = self._new_c()
     283        res._x = self._x + (<FunctionFieldElement>right)._x
     284        return res
     285
     286    cpdef ModuleElement _sub_(self, ModuleElement right):
     287        """
     288        EXAMPLES::
     289
     290            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     291            sage: (2*Y + x/(1+x^3))  -  (3*Y + 5*x*Y)         # indirect doctest
     292            (-5*x - 1)*Y + x/(x^3 + 1)
     293        """
     294        cdef FunctionFieldElement res = self._new_c()
     295        res._x = self._x - (<FunctionFieldElement>right)._x
     296        return res
     297
     298    cpdef RingElement _mul_(self, RingElement right):
     299        """
     300        EXAMPLES::
     301
     302            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     303            sage: Y  *  (3*Y + 5*x*Y)                          # indirect doctest
     304            (5*x^2 + 3*x)*Y - 20*x^4 - 12*x^3
     305        """
     306        cdef FunctionFieldElement res = self._new_c()
     307        res._x = (self._x * (<FunctionFieldElement>right)._x) % self._parent.polynomial()
     308        return res
     309
     310    cpdef RingElement _div_(self, RingElement right):
     311        """
     312        EXAMPLES::
     313
     314            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     315            sage: (2*Y + x/(1+x^3))  /  (2*Y + x/(1+x^3))       # indirect doctest
     316            1
     317        """
     318        return self * ~right
     319
     320    def __invert__(self):
     321        """
     322        EXAMPLES::
     323
     324            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     325            sage: a = ~(2*Y + 1/x); a                           # indirect doctest
     326            (-x^2/(8*x^5 + x^2 + 1/2))*Y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
     327            sage: a*(2*Y + 1/x)
     328            1
     329        """
     330        P = self._parent
     331        return P(self._x.xgcd(P._polynomial)[1])
     332
     333    def list(self):
     334        """
     335        EXAMPLES::
     336
     337            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     338            sage: a = ~(2*Y + 1/x); a
     339            (-x^2/(8*x^5 + x^2 + 1/2))*Y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
     340            sage: a.list()
     341            [(2*x^3 + x)/(16*x^5 + 2*x^2 + 1), -x^2/(8*x^5 + x^2 + 1/2)]
     342            sage: (x*Y).list()
     343            [0, x]
     344        """
     345        return self._x.padded_list(self.parent().degree())
     346       
     347
     348cdef class FunctionFieldElement_rational(FunctionFieldElement):
     349    """
     350    EXAMPLES::
     351   
     352        sage: FunctionField(QQ, 't')
     353        Rational function field in t over Rational Field
     354    """
     355    def __init__(self, parent, x):
     356        """
     357        EXAMPLES::
     358       
     359            sage: FunctionField(QQ,'t').gen()^3
     360            t^3
     361        """
     362        FieldElement.__init__(self, parent)
     363        self._x = x
     364
     365    # nonoptimized
     366
     367    def element(self):
     368        """
     369        Return the underlying fraction field element that represents this element.
     370
     371        EXAMPLES::
     372
     373            sage: R.<a> = FunctionField(GF(7))
     374            sage: a.element()
     375            a
     376            sage: type(a.element())
     377            <type 'sage.rings.fraction_field_element.FractionFieldElement'>       
     378        """
     379        return self._x
     380
     381    def list(self):
     382        """
     383        EXAMPLES::
     384
     385            sage: K.<t> = FunctionField(QQ)
     386            sage: t.list()
     387            [t]
     388        """
     389        return [self]
     390
     391    def _repr_(self):
     392        """
     393        EXAMPLES::
     394
     395            sage: K.<t> = FunctionField(QQ)
     396            sage: t._repr_()
     397            't'
     398        """
     399        return repr(self._x)
     400       
     401    def __nonzero__(self):
     402        """
     403        EXAMPLES::
     404
     405            sage: K.<t> = FunctionField(QQ)
     406            sage: bool(t)
     407            True
     408            sage: bool(K(0))
     409            False
     410            sage: bool(K(1))
     411            True
     412        """
     413        return not not self._x
     414
     415    cdef int _cmp_c_impl(self, Element other) except -2:
     416        """
     417        EXAMPLES::
     418
     419            sage: K.<t> = FunctionField(QQ)
     420            sage: cmp(t, 0)
     421            1
     422            sage: cmp(t, t^2)
     423            -1
     424        """
     425        cdef int c = cmp(type(self), type(other))
     426        if c: return c
     427        cdef FunctionFieldElement left = <FunctionFieldElement>self
     428        cdef FunctionFieldElement right = <FunctionFieldElement>other
     429        c = cmp(left._parent, right._parent)
     430        return c or cmp(left._x, right._x)
     431
     432    cpdef ModuleElement _add_(self, ModuleElement right):
     433        """
     434        EXAMPLES::
     435       
     436            sage: K.<t> = FunctionField(QQ)
     437            sage: t + (3*t^3)                      # indirect doctest
     438            3*t^3 + t
     439        """
     440        cdef FunctionFieldElement res = self._new_c()
     441        res._x = self._x + (<FunctionFieldElement>right)._x
     442        return res
     443
     444    cpdef ModuleElement _sub_(self, ModuleElement right):
     445        """
     446        EXAMPLES::
     447
     448
     449            sage: K.<t> = FunctionField(QQ)
     450            sage: t - (3*t^3)                      # indirect doctest
     451            -3*t^3 + t
     452        """
     453        cdef FunctionFieldElement res = self._new_c()
     454        res._x = self._x - (<FunctionFieldElement>right)._x
     455        return res
     456
     457    cpdef RingElement _mul_(self, RingElement right):
     458        """
     459        EXAMPLES::
     460
     461            sage: K.<t> = FunctionField(QQ)
     462            sage: (t+1) * (t^2-1)                  # indirect doctest
     463            t^3 + t^2 - t - 1
     464        """
     465        cdef FunctionFieldElement res = self._new_c()
     466        res._x = self._x * (<FunctionFieldElement>right)._x
     467        return res
     468
     469    cpdef RingElement _div_(self, RingElement right):
     470        """
     471        EXAMPLES::
     472
     473            sage: K.<t> = FunctionField(QQ)
     474            sage: (t+1) / (t^2 - 1)                # indirect doctest
     475            1/(t - 1)
     476        """
     477        cdef FunctionFieldElement res = self._new_c()
     478        res._parent = self._parent.fraction_field()
     479        res._x = self._x / (<FunctionFieldElement>right)._x
     480        return res
     481
     482    def numerator(self):
     483        """
     484        EXAMPLES::
     485
     486            sage: K.<t> = FunctionField(QQ)
     487            sage: f = (t+1) / (t^2 - 1/3); f
     488            (t + 1)/(t^2 - 1/3)
     489            sage: f.numerator()
     490            t + 1
     491        """
     492        return self._x.numerator()
     493
     494    def denominator(self):
     495        """
     496        EXAMPLES::
     497
     498            sage: K.<t> = FunctionField(QQ)
     499            sage: f = (t+1) / (t^2 - 1/3); f
     500            (t + 1)/(t^2 - 1/3)
     501            sage: f.denominator()
     502            t^2 - 1/3
     503        """
     504        return self._x.denominator()
     505   
     506    def valuation(self, v):
     507        """
     508        EXAMPLES::
     509       
     510            sage: K.<t> = FunctionField(QQ)
     511            sage: f = (t-1)^2 * (t+1) / (t^2 - 1/3)^3
     512            sage: f.valuation(t-1)
     513            2
     514            sage: f.valuation(t)
     515            0
     516            sage: f.valuation(t^2 - 1/3)
     517            -3
     518        """
     519        R = self._parent._ring
     520        return self._x.valuation(R(self._parent(v)._x))
     521   
     522    def is_square(self):
     523        """
     524        Returns whether self is a square.
     525       
     526        EXAMPLES::
     527           
     528            sage: K.<t> = FunctionField(QQ)
     529            sage: t.is_square()
     530            False
     531            sage: (t^2/4).is_square()
     532            True
     533            sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square()
     534            True
     535           
     536            sage: K.<t> = FunctionField(GF(5))
     537            sage: (-t^2).is_square()
     538            True
     539            sage: (-t^2).sqrt()
     540            2*t
     541        """
     542        return self._x.is_square()
     543   
     544    def sqrt(self, all=False):
     545        """
     546        Returns the square root of self.
     547       
     548        EXMPLES::
     549       
     550            sage: K.<t> = FunctionField(QQ)
     551            sage: f = t^2 - 2 + 1/t^2; f.sqrt()
     552            (t^2 - 1)/t
     553            sage: f = t^2; f.sqrt(all=True)
     554            [t, -t]
     555           
     556        TESTS::
     557       
     558            sage: K(4/9).sqrt()
     559            2/3
     560            sage: K(0).sqrt(all=True)
     561            [0]
     562        """
     563        if all:
     564            return [self._parent(r) for r in self._x.sqrt(all=True)]
     565        else:
     566            return self._parent(self._x.sqrt())
     567
     568    def factor(self):
     569        """
     570        Factor this rational function.
     571       
     572        EXAMPLES::
     573
     574            sage: K.<t> = FunctionField(QQ)
     575            sage: f = (t+1) / (t^2 - 1/3)
     576            sage: f.factor()
     577            (t + 1) * (t^2 - 1/3)^-1
     578            sage: (7*f).factor()
     579            (7) * (t + 1) * (t^2 - 1/3)^-1
     580            sage: ((7*f).factor()).unit()
     581            7
     582            sage: (f^3).factor()
     583            (t + 1)^3 * (t^2 - 1/3)^-3
     584        """
     585        P = self.parent()
     586        F = self._x.factor()
     587        from sage.structure.factorization import Factorization
     588        return Factorization([(P(a),e) for a,e in F], unit=F.unit())
     589
     590    def inverse_mod(self, I):
     591        r"""
     592        Return an inverse of self modulo the integral ideal `I`, if
     593        defined, i.e., if `I` and self together generate the unit
     594        ideal.
     595
     596        EXAMPLES::
     597
     598            sage: R.<x> = FunctionField(QQ)
     599            sage: S = R.maximal_order(); I = S.ideal(x^2+1)
     600            sage: t = S(x+1).inverse_mod(I); t
     601            -1/2*x + 1/2
     602            sage: (t*(x+1) - 1) in I
     603            True           
     604        """
     605        f = I.gens()[0]._x
     606        assert f.denominator() == 1
     607        assert self._x.denominator() == 1
     608        return self.parent()(self._x.numerator().inverse_mod(f.numerator()))
  • new file sage/rings/function_field/function_field_ideal.py

    diff --git a/sage/rings/function_field/function_field_ideal.py b/sage/rings/function_field/function_field_ideal.py
    new file mode 100644
    - +  
     1from sage.rings.ideal import Ideal_generic
     2
     3class FunctionFieldIdeal(Ideal_generic):
     4    """
     5    A fractional ideal of a function field.
     6
     7    EXAMPLES::
     8
     9        sage: R.<x> = FunctionField(GF(7))
     10        sage: S = R.maximal_order(); I = S.ideal(x^3+1)
     11        sage: isinstance(I, sage.rings.function_field.function_field_ideal.FunctionFieldIdeal)
     12        True   
     13    """
     14    pass
     15
     16class FunctionFieldIdeal_module(FunctionFieldIdeal):
     17    """
     18    A fractional ideal specified by a finitely generated module over
     19    the integers of the base field.
     20
     21    EXAMPLES::
     22
     23    An ideal in a rational function field::
     24
     25        sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     26        sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     27        sage: I = M.ideal(y)
     28        sage: I
     29        Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1
     30        sage: I^2
     31        Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1   
     32    """
     33    def __init__(self, ring, module):
     34        """
     35        INPUT:
     36
     37            - ``ring`` -- an order in a function field
     38            - ``module`` -- a module
     39
     40        EXAMPLES::
     41
     42            sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     43            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     44            sage: I = M.ideal(y)
     45            sage: type(I)
     46            <class 'sage.rings.function_field.function_field_ideal.FunctionFieldIdeal_module'>
     47        """
     48        self._ring = ring
     49        self._module = module
     50        self._structure = ring.fraction_field().vector_space()
     51        V, from_V, to_V = self._structure
     52        gens = tuple([from_V(a) for a in module.basis()])
     53        Ideal_generic.__init__(self, ring, gens, coerce=False)
     54
     55    def __contains__(self, x):
     56        """
     57        Return True if x is in this ideal.
     58
     59        EXAMPLES::
     60
     61            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     62            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()
     63            sage: I = M.ideal_with_gens_over_base([1, y]);  I
     64            Ideal (1, y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     65            sage: y in I
     66            True
     67            sage: y/x in I
     68            False
     69            sage: y^2 - 2 in I
     70            True
     71        """
     72        return self._structure[2](x) in self._module
     73
     74    def module(self):
     75        """
     76        Return module over the maximal order of the base field that
     77        underlies self.
     78
     79        The formation of this module is compatible with the vector
     80        space corresponding to the function field.
     81
     82        OUTPUT:
     83
     84            - a module over the maximal order of the base field of self
     85
     86        EXAMPLES::
     87
     88            sage: R.<x> = FunctionField(GF(7))
     89            sage: S = R.maximal_order(); S
     90            Maximal order in Rational function field in x over Finite Field of size 7
     91            sage: R.polynomial_ring()
     92            Univariate Polynomial Ring in x over Rational function field in x over Finite Field of size 7
     93            sage: I = S.ideal_with_gens_over_base([x^2 + 1, x*(x^2+1)])
     94            sage: I.gens()
     95            (x^2 + 1,)
     96            sage: I.module()
     97            Free module of degree 1 and rank 1 over Maximal order in Rational function field in x over Finite Field of size 7
     98            User basis matrix:
     99            [x^2 + 1]
     100            sage: V, from_V, to_V = R.vector_space(); V
     101            Vector space of dimension 1 over Rational function field in x over Finite Field of size 7
     102            sage: I.module().is_submodule(V)
     103            True       
     104        """
     105        return self._module
     106
     107    def __add__(self, other):
     108        """
     109        Add together two ideals.
     110       
     111        EXAMPLES::
     112       
     113            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     114            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     115            sage: I = M.ideal(y); J = M.ideal(y+1)
     116            sage: Z = I + J; Z
     117            Ideal (y + 1, 6*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     118            sage: 1 in Z
     119            True
     120            sage: M.ideal(y^2) + M.ideal(y^3) == M.ideal(y^2,y^3)
     121            True
     122        """
     123        if not isinstance(other, FunctionFieldIdeal_module):
     124            other = self.ring().ideal(other)
     125        return FunctionFieldIdeal_module(self.ring(), self.module() + other.module())
     126
     127    def intersection(self, other):
     128        """
     129        Return the intersection of the ideals self and other.
     130       
     131        EXAMPLES::
     132
     133            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     134            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     135            sage: I = M.ideal(y^3); J = M.ideal(y^2)
     136            sage: Z = I.intersection(J); Z
     137            Ideal (6*x^6 + 5*x^3 + 6, (6*x^3 + 6)*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     138            sage: y^2 in Z
     139            False
     140            sage: y^3 in Z
     141            True
     142        """
     143        if not isinstance(other, FunctionFieldIdeal_module):
     144            other = self.ring().ideal(other)
     145        if self.ring() != other.ring():
     146            raise ValueError, "rings must be the same"
     147        return FunctionFieldIdeal_module(self.ring(), self.module().intersection(other.module()))
     148
     149    def __cmp__(self, other):
     150        """
     151        Compare self and other.
     152       
     153        EXAMPLES::
     154
     155            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     156            sage: L.<y> = R.extension(y^2 - x^3 - 1)
     157            sage: M = L.equation_order()   
     158            sage: I = M.ideal(y*(y+1)); J = M.ideal((y^2-2)*(y+1))
     159            sage: I+J == J+I            # indirect test
     160            True
     161            sage: I == J
     162            False
     163            sage: I < J
     164            True
     165            sage: J < I
     166            False       
     167        """
     168        if not isinstance(other, FunctionFieldIdeal_module):
     169            other = self.ring().ideal(other)
     170        if self.ring() != other.ring():
     171            raise ValueError, "rings must be the same"
     172        return cmp(self.module(), other.module())
     173
     174    def __invert__(self):
     175        """
     176        Return the inverse of this fractional ideal.
     177
     178        EXAMPLES::
     179
     180            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     181            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     182            sage: I = M.ideal(y)
     183            sage: I.__invert__()
     184            Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     185            sage: I^(-1)
     186            Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     187            sage: I.__invert__() * I
     188            Ideal (1, 6*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     189        """
     190        if len(self.gens()) == 0:
     191            raise ZeroDivisionError
     192
     193        # NOTE: If  I = (g0, ..., gn), then {x : x*I is in R}
     194        # is the intersection over i of {x : x*gi is in R}
     195        # Thus (I + J)^(-1) = I^(-1) intersect J^(-1).
     196       
     197        G = self.gens()
     198        R = self.ring()
     199        inv = R.ideal(~G[0])
     200        for g in G[1:]:
     201            inv = inv.intersection(R.ideal(~g))
     202        return inv
     203
     204def ideal_with_gens(R, gens):
     205    """
     206    Return fractional ideal in the order of R with given generators
     207    over R.
     208
     209    EXAMPLES::
     210
     211        sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     212        sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     213        sage: sage.rings.function_field.function_field_ideal.ideal_with_gens(M, [y])
     214        Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1
     215    """
     216    K = R.fraction_field()
     217    return ideal_with_gens_over_base(R, [b*K(g) for b in R.basis() for g in gens])
     218   
     219
     220def ideal_with_gens_over_base(R, gens):
     221    """
     222    Return fractional ideal in the given order R with given generators
     223    over the maximal order of the base field.
     224
     225    EXAMPLES::
     226
     227        sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     228        sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
     229        sage: sage.rings.function_field.function_field_ideal.ideal_with_gens_over_base(M, [x^3+1,-y])
     230        Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1   
     231    """
     232    K = R.fraction_field()
     233    V, from_V, to_V = K.vector_space()
     234
     235    # We handle the case of a rational function field separately,
     236    # since this is the base case and is used, e.g,. internally
     237    # by the linear algebra Hermite form code.
     238    import function_field_order
     239    if isinstance(R, function_field_order.FunctionFieldOrder_rational):
     240        try:
     241            v = R._ring.ideal([x.element() for x in gens]).gens_reduced()
     242            assert len(v) == 1
     243            basis = [to_V(v[0])]
     244            M = V.span_of_basis(basis, check=False, already_echelonized=True, base_ring=R)
     245        except Exception, msg:
     246            print msg   # TODO --for debugging
     247            raise
     248    else:
     249        # General case
     250        S = V.base_field().maximal_order()
     251        M = V.span([to_V(b) for b in gens], base_ring=S)
     252
     253    return FunctionFieldIdeal_module(R, M)
  • new file sage/rings/function_field/function_field_order.py

    diff --git a/sage/rings/function_field/function_field_order.py b/sage/rings/function_field/function_field_order.py
    new file mode 100644
    - +  
     1"""
     2Orders in Function Fields
     3"""
     4
     5from sage.structure.parent_gens import ParentWithGens
     6
     7from sage.rings.ring import IntegralDomain, PrincipalIdealDomain
     8
     9from sage.rings.ideal import is_Ideal
     10
     11class FunctionFieldOrder(IntegralDomain):
     12    def __init__(self, fraction_field):
     13        """
     14        EXAMPLES::
     15
     16            sage: R = FunctionField(QQ,'y').maximal_order()
     17            sage: isinstance(R, sage.rings.function_field.function_field_order.FunctionFieldOrder)
     18            True
     19        """
     20        self._fraction_field = fraction_field
     21
     22    def _repr_(self):
     23        """
     24        EXAMPLES::
     25
     26            sage: FunctionField(QQ,'y').maximal_order()._repr_()
     27            'Maximal order in Rational function field in y over Rational Field'
     28        """
     29        return "Order in %s"%self.fraction_field()
     30
     31    def is_finite(self):
     32        """
     33        EXAMPLES::
     34
     35            sage: FunctionField(QQ,'y').maximal_order().is_finite()
     36            False
     37        """
     38        return False
     39
     40    def is_field(self, proof=True):
     41        """
     42        EXAMPLES::
     43
     44            sage: FunctionField(QQ,'y').maximal_order().is_field()
     45            False
     46        """
     47        return False
     48
     49    def is_noetherian(self):
     50        """
     51        Return True, since orders in function fields are noetherian.
     52       
     53        EXAMPLES::
     54
     55            sage: FunctionField(QQ,'y').maximal_order().is_noetherian()
     56            True
     57        """
     58        return True
     59
     60    def fraction_field(self):
     61        """
     62        EXAMPLES::
     63
     64            sage: FunctionField(QQ,'y').maximal_order().fraction_field()
     65            Rational function field in y over Rational Field
     66        """
     67        return self._fraction_field
     68
     69    def ideal_with_gens_over_base(self, gens):
     70        """
     71        Return the fractional ideal with given generators over the
     72        maximal ideal of the base field.  That this is really an ideal
     73        is not checked.
     74
     75        INPUT:
     76
     77            - ``basis`` -- list of elements that are a basis for the
     78              ideal over the maximal order of the base field
     79           
     80        EXAMPLES::
     81
     82        We construct an ideal in a rational function field::
     83       
     84            sage: R.<y> = FunctionField(QQ)
     85            sage: S = R.maximal_order()
     86            sage: I = S.ideal_with_gens_over_base([y]); I
     87            Ideal (y) of Maximal order in Rational function field in y over Rational Field
     88            sage: I*I
     89            Ideal (y^2) of Maximal order in Rational function field in y over Rational Field
     90
     91        We construct some ideals in a nontrivial function field::
     92
     93            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     94            sage: L.<y> = R.extension(y^2 - x^3 - 1)
     95            sage: M = L.equation_order(); M
     96            Order in Function field in y defined by y^2 + 6*x^3 + 6
     97            sage: I = M.ideal_with_gens_over_base([1, y]);  I
     98            Ideal (1, y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     99            sage: I.module()
     100            Free module of degree 2 and rank 2 over Maximal order in Rational function field in x over Finite Field of size 7
     101            Echelon basis matrix:
     102            [1 0]
     103            [0 1]
     104        """
     105        from function_field_ideal import ideal_with_gens_over_base
     106        return ideal_with_gens_over_base(self, [self(a) for a in gens])
     107
     108    def ideal(self, *gens):
     109        """
     110        Return the fractional ideal generated by the element gens or
     111        the elements in gens if gens is a list.
     112
     113        EXAMPLES::
     114
     115            sage: R.<y> = FunctionField(QQ)
     116            sage: S = R.maximal_order()
     117            sage: S.ideal(y)
     118            Ideal (y) of Maximal order in Rational function field in y over Rational Field
     119
     120        A fractional ideal of a nontrivial extension::
     121
     122            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     123            sage: L.<y> = R.extension(y^2 - x^3 - 1)
     124            sage: M = L.equation_order()
     125            sage: M.ideal(1/y)
     126            Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6       
     127        """
     128        if len(gens) == 1:
     129            gens = gens[0]
     130            if not isinstance(gens, (list, tuple)):
     131                gens = [gens]
     132        from function_field_ideal import ideal_with_gens
     133        return ideal_with_gens(self, gens)
     134
     135
     136       
     137   
     138
     139class FunctionFieldOrder_basis(FunctionFieldOrder):
     140    """
     141    An order given by a basis over the maximal order of the base
     142    field.
     143    """
     144    def __init__(self, basis, check=True):
     145        """
     146        EXAMPLES::
     147
     148            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]; L.<Y> = K.extension(y^4 + x*y + 4*x + 1); S = L.equation_order()
     149            sage: S
     150            Order in Function field in Y defined by y^4 + x*y + 4*x + 1
     151            sage: type(S)
     152            <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_basis'>
     153        """
     154        if len(basis) == 0:
     155            raise ValueError, "basis must have positive length"
     156       
     157        fraction_field = basis[0].parent()
     158        if len(basis) != fraction_field.degree():
     159            raise ValueError, "length of basis must equal degree of field"
     160       
     161        FunctionFieldOrder.__init__(self, fraction_field)
     162       
     163        self._basis = tuple(basis)
     164        V, fr, to = fraction_field.vector_space()
     165        R = fraction_field.base_field().maximal_order()
     166        self._module = V.span([to(b) for b in basis], base_ring=R)
     167        self._ring = fraction_field.polynomial_ring()
     168        self._populate_coercion_lists_(coerce_list=[self._ring])
     169        if check:
     170            if self._module.rank() != fraction_field.degree():
     171                raise ValueError, "basis is not a basis"
     172        IntegralDomain.__init__(self, self, names = fraction_field.variable_names(), normalize = False)
     173
     174    def _element_constructor_(self, f):
     175        """
     176        EXAMPLES::
     177
     178            sage: R.<y> = FunctionField(QQ)
     179            sage: R.maximal_order()._element_constructor_(y)
     180            y
     181        """
     182        # HUGE TODO: have to check that f is really in self!!
     183        if f.parent() is self.fraction_field():
     184            f = f.element()
     185        elif f.parent() is self._ring:
     186            return function_field_element.FunctionFieldElement_rational(self, f)
     187        return function_field_element.FunctionFieldElement_rational(self, self._ring(f))
     188
     189    def fraction_field(self):
     190        """
     191        EXAMPLES::
     192
     193            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]; L.<Y> = K.extension(y^4 + x*y + 4*x + 1); S = L.equation_order()           
     194            sage: S.fraction_field()
     195            Function field in Y defined by y^4 + x*y + 4*x + 1
     196        """
     197        return self._fraction_field
     198
     199    def basis(self):
     200        """
     201        EXAMPLES::
     202
     203            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]; L.<Y> = K.extension(y^4 + x*y + 4*x + 1); S = L.equation_order()           
     204            sage: S.basis()
     205            (1, Y, Y^2, Y^3)
     206        """
     207        return self._basis
     208
     209    def free_module(self):
     210        """
     211        EXAMPLES::
     212
     213            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]; L.<Y> = K.extension(y^4 + x*y + 4*x + 1); S = L.equation_order()
     214            sage: S.free_module()
     215            Free module of degree 4 and rank 4 over Maximal order in Rational function field in x over Finite Field of size 7
     216            Echelon basis matrix:
     217            [1 0 0 0]
     218            [0 1 0 0]
     219            [0 0 1 0]
     220            [0 0 0 1]       
     221        """
     222        return self._module
     223
     224##     def polynomial_quotient_ring(self):
     225##         """
     226##         Return a quotient of a (possibly multivariate) polynomial ring
     227##         that is isomorphic to self, along with morphisms back and
     228##         forth.
     229##         """
     230##         raise NotImplementedError
     231   
     232
     233import function_field_element   
     234       
     235class FunctionFieldOrder_rational(PrincipalIdealDomain, FunctionFieldOrder):
     236    """
     237    The maximal order in a rational function field.
     238    """
     239    def __init__(self, function_field):
     240        """
     241        EXAMPLES::
     242       
     243            sage: K.<t> = FunctionField(GF(19)); K
     244            Rational function field in t over Finite Field of size 19
     245            sage: R = K.maximal_order(); R
     246            Maximal order in Rational function field in t over Finite Field of size 19
     247            sage: type(R)
     248            <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_rational'>
     249        """
     250        FunctionFieldOrder.__init__(self, function_field)
     251        IntegralDomain.__init__(self, self, names = function_field.variable_names(), normalize = False)
     252        self._ring = function_field._ring
     253        self._populate_coercion_lists_(coerce_list=[self._ring])
     254        self._gen = self(self._ring.gen())
     255        self._basis = (self(1),)
     256
     257    def basis(self):
     258        """
     259        Return basis (=1) for this order as a module over the polynomial ring.
     260       
     261        EXAMPLES::
     262
     263            sage: K.<t> = FunctionField(GF(19))
     264            sage: M = K.maximal_order()
     265            sage: M.basis()
     266            (1,)
     267            sage: parent(M.basis()[0])
     268            Maximal order in Rational function field in t over Finite Field of size 19
     269        """
     270        return self._basis
     271       
     272    def ideal(self, *gens):
     273        """
     274        Return the fractional ideal generated by the element gens or
     275        the elements in gens if gens is a list.
     276
     277        EXAMPLES::
     278
     279            sage: R.<y> = FunctionField(QQ)
     280            sage: S = R.maximal_order()
     281            sage: S.ideal(y)
     282            Ideal (y) of Maximal order in Rational function field in y over Rational Field
     283
     284        A fractional ideal of a nontrivial extension::
     285
     286            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     287            sage: L.<y> = R.extension(y^2 - x^3 - 1)
     288            sage: M = L.equation_order()
     289            sage: M.ideal(1/y)
     290            Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     291
     292        A non-principal ideal::
     293
     294            sage: R.<x> = FunctionField(GF(7))
     295            sage: S = R.maximal_order()
     296            sage: S.ideal(x^3+1,x^3+6)
     297            Ideal (1) of Maximal order in Rational function field in x over Finite Field of size 7
     298            sage: S.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1))
     299            Ideal (x^2 + 1) of Maximal order in Rational function field in x over Finite Field of size 7   
     300        """
     301        if len(gens) == 1:
     302            gens = gens[0]
     303            if not isinstance(gens, (list, tuple)):
     304                if is_Ideal(gens):
     305                    gens = gens.gens()
     306                else:
     307                    gens = [gens]
     308        from function_field_ideal import ideal_with_gens
     309        return ideal_with_gens(self, gens)
     310
     311    def _repr_(self):
     312        """
     313        EXAMPLES::
     314           
     315            sage: FunctionField(QQ,'y').maximal_order()._repr_()
     316            'Maximal order in Rational function field in y over Rational Field'
     317        """
     318        return "Maximal order in %s"%self.fraction_field()
     319
     320    def gen(self, n=0):
     321        """
     322        EXAMPLES::
     323
     324            sage: R = FunctionField(QQ,'y').maximal_order(); R.gen()
     325            y
     326            sage: R.gen(1)
     327            Traceback (most recent call last):
     328            ...
     329            IndexError: Only one generator.
     330        """
     331        if n != 0: raise IndexError, "Only one generator."
     332        return self._gen
     333
     334    def ngens(self):
     335        """
     336        EXAMPLES::
     337
     338            sage: R = FunctionField(QQ,'y').maximal_order(); R.ngens()
     339            1
     340        """
     341        return 1
     342
     343    def _element_constructor_(self, f):
     344        """
     345        EXAMPLES::
     346
     347            sage: R.<y> = FunctionField(QQ)
     348            sage: R.maximal_order()._element_constructor_(y)
     349            y
     350        """
     351        # HUGE TODO: have to check that f is really in self!!
     352       
     353        if f.parent() is self.fraction_field():
     354            f = f.element()
     355        if f.parent() is self._ring:
     356            return function_field_element.FunctionFieldElement_rational(self, f)
     357        return function_field_element.FunctionFieldElement_rational(self, self._ring(f))
     358
     359##     def polynomial_quotient_ring(self):
     360##         """
     361##         Return a quotient of a (possibly multivariate) polynomial ring
     362##         that is isomorphic to self, along with morphisms back and
     363##         forth.
     364
     365##         EXAMPLES::
     366##         """
     367##         return self._ring
     368
     369   
     370       
     371       
  • new file sage/rings/function_field/maps.py

    diff --git a/sage/rings/function_field/maps.py b/sage/rings/function_field/maps.py
    new file mode 100644
    - +  
     1r"""
     2
     3"""
     4
     5from sage.categories.map import Map
     6from sage.categories.homset import Hom
     7
     8from function_field_order import FunctionFieldOrder
     9
     10class FunctionFieldIsomorphism(Map):
     11    r"""
     12    A base class for various isomorphisms between function fields and
     13    vector spaces.
     14
     15    EXAMPLES::
     16
     17        sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     18        sage: V, f, t = L.vector_space()
     19        sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldIsomorphism)
     20        True
     21    """
     22    def _repr_type(self):
     23        """
     24        Return the type of this map (an isomorphism), for the purposes of printing out self. 
     25       
     26        EXAMPLES::
     27
     28            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     29            sage: V, f, t = L.vector_space()
     30            sage: f._repr_type()
     31            'Isomorphism'
     32        """
     33        return "Isomorphism"
     34
     35    def is_injective(self):
     36        """
     37        Return True, since this isomorphism is injective.
     38       
     39        EXAMPLES::
     40
     41            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     42            sage: V, f, t = L.vector_space()           
     43            sage: f.is_injective()
     44            True
     45        """
     46        return True
     47
     48    def is_surjective(self):
     49        """
     50        Return True, since this isomorphism is surjective.
     51       
     52        EXAMPLES::
     53
     54            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     55            sage: V, f, t = L.vector_space()           
     56            sage: f.is_surjective()
     57            True
     58        """
     59        return True
     60
     61class MapVectorSpaceToFunctionField(FunctionFieldIsomorphism):
     62    r"""
     63    An isomorphism from a vector space and a function field.
     64   
     65    EXAMPLES:
     66
     67        sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     68        sage: V, f, t = L.vector_space(); f
     69        Isomorphism map:
     70          From: Vector space of dimension 2 over Rational function field in x over Rational Field
     71          To:   Function field in Y defined by y^2 - x*y + 4*x^3
     72    """
     73    def __init__(self, V, K):
     74        """
     75        EXAMPLES::
     76       
     77            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     78            sage: V, f, t = L.vector_space(); type(f)
     79            <class 'sage.rings.function_field.maps.MapVectorSpaceToFunctionField'>
     80        """
     81        self._V = V
     82        self._K = K
     83        self._R = K.polynomial_ring()
     84        FunctionFieldIsomorphism.__init__(self, Hom(V, K))
     85
     86    def _call_(self, v):
     87        """
     88        EXAMPLES::
     89
     90            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     91            sage: V, f, t = L.vector_space()                       
     92            sage: f(x*V.0 + (1/x^3)*V.1)         # indirect doctest
     93            1/x^3*Y + x
     94        """
     95        f = self._R(self._V(v).list())
     96        return self._K(f)
     97
     98    def domain(self):
     99        """
     100        EXAMPLES::
     101
     102            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     103            sage: V, f, t = L.vector_space()                                   
     104            sage: f.domain()
     105            Vector space of dimension 2 over Rational function field in x over Rational Field
     106        """
     107        return self._V
     108
     109    def codomain(self):
     110        """
     111        EXAMPLES::
     112
     113            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     114            sage: V, f, t = L.vector_space()                                   
     115            sage: f.codomain()
     116            Function field in Y defined by y^2 - x*y + 4*x^3
     117        """
     118        return self._K
     119
     120
     121class MapFunctionFieldToVectorSpace(FunctionFieldIsomorphism):
     122    """
     123    An isomorphism from a function field to a vector space.
     124   
     125    EXAMPLES::
     126
     127        sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     128        sage: V, f, t = L.vector_space(); t
     129        Isomorphism map:
     130          From: Function field in Y defined by y^2 - x*y + 4*x^3
     131          To:   Vector space of dimension 2 over Rational function field in x over Rational Field
     132    """
     133    def __init__(self, K, V):
     134        """
     135        EXAMPLES::
     136
     137            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     138            sage: V, f, t = L.vector_space(); type(t)
     139            <class 'sage.rings.function_field.maps.MapFunctionFieldToVectorSpace'>
     140        """
     141        self._V = V
     142        self._K = K
     143        self._zero = K.base_ring()(0)
     144        self._n = K.degree()
     145        FunctionFieldIsomorphism.__init__(self, Hom(K, V))
     146
     147    def domain(self):
     148        """
     149        EXAMPLES::
     150
     151            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     152            sage: V, f, t = L.vector_space()                                   
     153            sage: t.domain()
     154            Function field in Y defined by y^2 - x*y + 4*x^3
     155        """
     156        return self._K
     157
     158    def codomain(self):
     159        """
     160        EXAMPLES::
     161
     162            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     163            sage: V, f, t = L.vector_space()                                   
     164            sage: t.codomain()
     165            Vector space of dimension 2 over Rational function field in x over Rational Field       
     166        """
     167        return self._V
     168
     169    def _repr_type(self):
     170        """
     171        EXAMPLES::
     172
     173            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     174            sage: V, f, t = L.vector_space()
     175            sage: t._repr_type()
     176            'Isomorphism'
     177        """
     178        return "Isomorphism"
     179   
     180    def _call_(self, x):
     181        """
     182        EXAMPLES::
     183
     184            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
     185            sage: V, f, t = L.vector_space()                                   
     186            sage: t(x + (1/x^3)*Y)                       # indirect doctest
     187            (x, 1/x^3)
     188        """
     189        y = self._K(x)
     190        v = y.list()
     191        w = v + [self._zero]*(self._n - len(v))
     192        return self._V(w)
     193
     194
     195##########################################################################
     196# Morphisms between function fields
     197
     198class FunctionFieldMorphism(Map):
     199    """
     200    EXAMPLES::
     201
     202        sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     203        sage: L.<y> = R.extension(y^2 - x^2)
     204        sage: f = L.hom(-y); f
     205        Morphism of function fields defined by y |--> -y   
     206    """
     207    def __init__(self, parent, im_gen, base_morphism):
     208        """
     209        EXAMPLES::
     210
     211            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     212            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2); f
     213            Morphism of function fields defined by y |--> 2*y
     214            sage: type(f)
     215            <class 'sage.rings.function_field.maps.FunctionFieldMorphism'>
     216            sage: factor(L.polynomial())
     217            y^3 + 6*x^3 + x
     218            sage: f(y).charpoly('y')
     219            y^3 + 6*x^3 + x
     220        """
     221        self._im_gen = im_gen
     222        self._base_morphism = base_morphism
     223        Map.__init__(self, parent)
     224        # Verify that the morphism is valid:
     225        R = self.codomain()['X']
     226        v = parent.domain().polynomial().list()
     227        if base_morphism is not None:
     228            v = [base_morphism(a) for a in v]
     229        f = R(v)
     230        if f(im_gen):
     231            raise ValueError, "invalid morphism"
     232   
     233    def is_injective(self):
     234        """
     235        EXAMPLES::
     236
     237            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     238            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     239            sage: f.is_injective()
     240            True
     241        """
     242        return True
     243
     244    def __repr__(self):
     245        """
     246        EXAMPLES::
     247
     248            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     249            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     250            sage: f.__repr__()     
     251            'Morphism of function fields defined by y |--> 2*y'
     252        """
     253        return "Morphism of function fields defined by %s"%self._short_repr()
     254
     255    def __nonzero__(self):
     256        """
     257        EXAMPLES::
     258
     259            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     260            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     261            sage: f.__nonzero__()
     262            True
     263            sage: bool(f)
     264            True
     265        """
     266        return True
     267
     268    def _short_repr(self):
     269        """
     270        EXAMPLES::
     271
     272            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     273            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     274            sage: f._short_repr()
     275            'y |--> 2*y'
     276        """
     277        a = '%s |--> %s'%(self.domain().gen(), self._im_gen)
     278        if self._base_morphism is not None:
     279            a += ',  ' + self._base_morphism._short_repr()
     280        return a
     281   
     282    def _call_(self, x):
     283        """
     284        EXAMPLES::
     285
     286            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     287            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     288            sage: f(y/x + x^2/(x+1))            # indirect doctest
     289            2/x*y + x^2/(x + 1)
     290            sage: f(y)
     291            2*y
     292        """
     293        v = x.list()
     294        if self._base_morphism is not None:
     295            v = [self._base_morphism(a) for a in v]
     296        f = v[0].parent()['X'](v)
     297        return f(self._im_gen)
     298
     299class FunctionFieldMorphism_rational(FunctionFieldMorphism):
     300    def __init__(self, parent, im_gen):
     301        """
     302        EXAMPLES::
     303
     304            sage: R.<x> = FunctionField(GF(7)); f = R.hom(1/x); f
     305            Morphism of function fields defined by x |--> 1/x
     306            sage: type(f)
     307            <class 'sage.rings.function_field.maps.FunctionFieldMorphism_rational'>
     308        """
     309        Map.__init__(self, parent)
     310        self._im_gen = im_gen
     311        self._base_morphism = None
     312
     313    def _call_(self, x):
     314        """
     315        EXAMPLES::
     316
     317            sage: R.<x> = FunctionField(GF(7)); f = R.hom(1/x); f
     318            Morphism of function fields defined by x |--> 1/x
     319            sage: f(x+1)                          # indirect doctest
     320            (x + 1)/x
     321            sage: 1/x + 1
     322            (x + 1)/x       
     323        """
     324        a = x.element()
     325        return a.subs({a.parent().gen():self._im_gen})
  • new file sage/rings/function_field/todo.txt

    diff --git a/sage/rings/function_field/todo.txt b/sage/rings/function_field/todo.txt
    new file mode 100644
    - +  
     1TODO:
     2
     3[ ] copyright headers
     4[ ] Docstring headers for each file with description of content of file
     5[ ] picling elements
     6
     7[ ] RR space algorithm
     8
     9[ ] implement denominator in general, which is a guaranteed multiple of the denominator
     10    only when not pid...
     11[ ] reduction of divisors: algorithm
     12[ ] polynomial factoring of any univariate poly over a non-rational function field
     13[ ] checking irreducibility in FunctionField_polymod constructor
     14[ ] pickle doctests
     15[ ] TestSuite(s).run() doctests
     16[ ] method function_field() on algebraic curves, that give back a corresponding function field object.
     17[ ] compute maximal separable subfield (requested by Voloch)
     18[ ] factoring polynomials in n variables over rational function field
     19[ ] x.valuation(...)  [bradshaw will do this]
     20[ ] optimization: new implementation of the function field API, but
     21    using multivariate poly rings in some cases; for *speed*, but with
     22    less base rings supported...?
     23
     24DONE:
     25[x] phi = morphism; phi(order); phi(ideal) --- won't do, since image of order or ideal often isn't one
     26    for general morphisms
     27[x] a command FunctionField to make a new function field from anything.
     28[x] constant_base_field versus constant_field
     29[x] fix when asking for equation order if defining polynomial not *integral*
     30[x] non-monic defining polynomials
     31[x] do not require defining polynomial to be monic
     32[x] issue with *underscores* and singular:
     33K.<t_ba> = FunctionField(QQ)
     34R.<u_ba> = K[]
     35L.<u_ba> = K.extension(u_ba^2 - t_ba)
     36L.equation_order()
     37BOOM!
     38
     39[x] isomorphisms between function fields:
     40     K.hom([top gen, next one down, etc.])
     41    make sure you include easy way to gens all the way down.
     42[x] inverses of fractional ideals
     43[x] factor for elements of the rational function field
     44[x] ideals
     45[x] polynomial factoring of any univariate poly over a rational function field: reduce to bivariate over constant field?
     46[x] conversion back and forth between a free module over base
     47[x] random element
     48[x] numerator, denominator
     49[x] 100% coverage
     50[x] matrix of element
     51[x] norm
     52[x] trace
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/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
     
    23292330                X[i] = c
    23302331        return X
    23312332
    2332     def factor(self):
     2333    def factor(self, proof=True):
    23332334        r"""
    23342335        Return the factorization of self over the base ring of this
    23352336        polynomial. Factoring polynomials over
     
    28042805            else:
    28052806                G = self._pari_with_name('x').factor()
    28062807
     2808        elif sage.rings.function_field.function_field.is_FunctionField(R):
     2809            return R._factor_univariate_polynomial(self, proof=proof)
     2810
    28072811        #elif padic_field.is_pAdicField(R):
    28082812        #    G = list(self._pari_with_name('x').factorpadic(R.prime(), R.prec()))
    28092813           
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b  
    415415
    416416        - element_constructor -- A class or function that creates
    417417          elements of this Parent given appropriate input (can also be
    418           filled in later with ``_populate_coercion_lists_``
     418          filled in later with ``_populate_coercion_lists_``)
    419419
    420420        - gens -- Generators for this object (can also be filled in
    421421          later with ``_populate_generators_``)
     
    12301230           return self.Hom(codomain)(im_gens, check=check)
    12311231   
    12321232    #################################################################################
    1233     # New New Coercion support functionality
     1233    # New Coercion support functionality
    12341234    #################################################################################
    12351235   
    12361236    def _populate_coercion_lists_(self,
  • setup.py

    diff --git a/setup.py b/setup.py
    a b  
    884884
    885885                     'sage.rings',
    886886                     'sage.rings.finite_rings',
     887                     'sage.rings.function_field',
    887888                     'sage.rings.number_field',
    888889                     'sage.rings.padics',
    889890                     'sage.rings.polynomial',