Ticket #9054: 9054_function_fields.patch

File 9054_function_fields.patch, 130.8 KB (added by jdemeyer, 6 years ago)
  • new file doc/en/reference/function_fields.rst

    # HG changeset patch
    # User Moritz Minzlaff <minzlaff@daad-alumni.de>
    # Date 1301395342 -7200
    # Node ID 8b937382f6df038b680e6a91fdcd0f830ecbd0ef
    # Parent  7b8d99242906b230cd18e1abd285aa9ac063776c
    Provide basic function field arithmetic (combined patch by various authors)
    
    diff --git a/doc/en/reference/function_fields.rst b/doc/en/reference/function_fields.rst
    new file mode 100644
    - +  
     1Algebraic Function Fields
     2=========================
     3
     4.. toctree::
     5   :maxdepth: 2
     6
     7   sage/rings/function_field/function_field
     8   sage/rings/function_field/function_field_element
     9   sage/rings/function_field/function_field_order
     10   sage/rings/function_field/function_field_ideal
     11   sage/rings/function_field/maps
     12   sage/rings/function_field/constructor
  • doc/en/reference/index.rst

    diff --git a/doc/en/reference/index.rst b/doc/en/reference/index.rst
    a b  
    7171   rings_standard
    7272   rings_numerical
    7373   number_fields
     74   function_fields
    7475   padics
    7576   polynomial_rings
    7677   power_series
  • module_list.py

    diff --git a/module_list.py b/module_list.py
    a b  
    13961396
    13971397        ################################
    13981398        ##
     1399        ## sage.rings.function_field
     1400        ##
     1401        ################################
     1402
     1403    Extension('sage.rings.function_field.function_field_element',
     1404              sources = ['sage/rings/function_field/function_field_element.pyx']),
     1405
     1406        ################################
     1407        ##
    13991408        ## sage.rings.number_field
    14001409        ##
    14011410        ################################
  • sage/categories/all.py

    diff --git a/sage/categories/all.py b/sage/categories/all.py
    a b  
    4141
    4242# fields
    4343from number_fields import NumberFields
     44from function_fields import FunctionFields
    4445
    4546# modules
    4647from left_modules import LeftModules
  • 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"""
     2Function fields
     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
     17
     18class FunctionFields(Category):
     19    r"""
     20    The category of function fields.
     21
     22    EXAMPLES:
     23
     24    We create the category of function fields::
     25
     26        sage: C = FunctionFields()
     27        sage: C
     28        Category of function fields
     29
     30    TESTS::
     31
     32        sage: TestSuite(FunctionFields()).run()
     33    """
     34    @cached_method
     35    def super_categories(self):
     36        """
     37        Returns the Category of which this is a direct sub-Category
     38        For a list off all super caategories see all_super_categories
     39
     40        EXAMPLES::
     41
     42            sage: FunctionFields().super_categories()
     43            [Category of fields]
     44        """
     45        return[Fields()]
     46
     47    def _call_(self, x):
     48        r"""
     49        Constructs an object in this category from the data in ``x``,
     50        or throws a TypeError.
     51
     52        EXAMPLES::
     53
     54            sage: C = FunctionFields()
     55            sage: K.<x>=FunctionField(QQ)
     56            sage: C(K)
     57            Rational function field in x over Rational Field
     58            sage: Ky.<y> = K[]
     59            sage: L = K.extension(y^2-x)
     60            sage: C(L)
     61            Function field in y defined by y^2 - x
     62            sage: C(L.equation_order())
     63            Function field in y defined by y^2 - x
     64        """
     65        try:
     66            return x.function_field()
     67        except AttributeError:
     68            raise  TypeError, "unable to canonically associate a function field to %s"%x
     69
     70    class ParentMethods:
     71        pass
     72
     73    class ElementMethods:
     74        pass
  • sage/matrix/matrix2.pyx

    diff --git a/sage/matrix/matrix2.pyx b/sage/matrix/matrix2.pyx
    a b  
    54675467            sage: C.echelon_form()
    54685468            Traceback (most recent call last):
    54695469            ...
    5470             NotImplementedError: Echelon form not implemented over 'Univariate Polynomial Ring in x over Integer Ring'.
     5470            NotImplementedError: Ideal Ideal (2, x + 1) of Univariate Polynomial Ring in x over Integer Ring not principal
     5471            Echelon form not implemented over 'Univariate Polynomial Ring in x over Integer Ring'.
    54715472            sage: C = matrix(3,[2,x,x^2,x+1,3-x,-1,3,2,1/2])
    54725473            sage: C.echelon_form()
    54735474            [                               2                                x                              x^2]
     
    55615562        else:
    55625563            try:
    55635564                a, d, p = self._echelon_form_PID()
    5564             except TypeError:
    5565                 raise NotImplementedError, "echelon form over %s not yet implemented"%self.base_ring()
     5565            except TypeError, msg:
     5566                raise NotImplementedError, "%s\nechelon form over %s not yet implemented"%(msg, self.base_ring())
    55665567
    55675568            for c from 0 <= c < self.ncols():
    55685569               for r from 0 <= r < self.nrows():
     
    57145715                    kwds['algorithm'] = algorithm
    57155716                return self._echelonize_ring(**kwds)
    57165717        except ArithmeticError, msg:
    5717             raise NotImplementedError, "Echelon form not implemented over '%s'."%self.base_ring()
     5718            raise NotImplementedError, "%s\nEchelon form not implemented over '%s'."%(msg,self.base_ring())
    57185719
    57195720    def echelon_form(self, algorithm="default", cutoff=0, **kwds):
    57205721        """
     
    1051810519        dp, up, vp = _smith_diag(d)
    1051910520        return dp,up*u,v*vp
    1052010521
     10522    def hermite_form(self, include_zero_rows=True, transformation=False):
     10523        """
     10524        Return the Hermite form of self, if it is defined.
     10525
     10526        INPUT:
     10527
     10528            - ``include_zero_rows`` -- bool (default: True); if False
     10529              the zero rows in the output matrix are deleted.
     10530
     10531            - ``transformation`` -- bool (default: False) a matrix U such that U*self == H.
     10532
     10533        OUTPUT:
     10534
     10535            - matrix H
     10536            - (optional) transformation matrix U such that U*self == H, possibly with zero
     10537              rows deleted...
     10538       
     10539
     10540        EXAMPLES::
     10541
     10542            sage: M = FunctionField(GF(7),'x').maximal_order()
     10543            sage: K.<x> = FunctionField(GF(7)); M = K.maximal_order()
     10544            sage: A = matrix(M, 2, 3, [x, 1, 2*x, x, 1+x, 2])
     10545            sage: A.hermite_form()
     10546            [      x       1     2*x]
     10547            [      0       x 5*x + 2]
     10548            sage: A.hermite_form(transformation=True)
     10549            (
     10550            [      x       1     2*x]  [1 0]
     10551            [      0       x 5*x + 2], [6 1]
     10552            )
     10553            sage: A = matrix(M, 2, 3, [x, 1, 2*x, 2*x, 2, 4*x])
     10554            sage: A.hermite_form(transformation=True, include_zero_rows=False)
     10555            ([  x   1 2*x], [1 0])
     10556            sage: H, U = A.hermite_form(transformation=True, include_zero_rows=True); H, U
     10557            (
     10558            [  x   1 2*x]  [1 0]
     10559            [  0   0   0], [5 1]
     10560            )
     10561            sage: U*A == H
     10562            True
     10563            sage: H, U = A.hermite_form(transformation=True, include_zero_rows=False)
     10564            sage: U*A
     10565            [  x   1 2*x]
     10566            sage: U*A == H
     10567            True
     10568        """
     10569        left, H, pivots = self._echelon_form_PID()
     10570        if not include_zero_rows:
     10571            i = H.nrows() - 1
     10572            while H.row(i) == 0:
     10573                i -= 1
     10574            H = H[:i+1]
     10575            if transformation:
     10576                left = left[:i+1]
     10577        if transformation:
     10578            return H, left
     10579        else:
     10580            return H
     10581
    1052110582    def _echelon_form_PID(self):
    1052210583        r"""
    1052310584        Return a triple (left, a, pivots) where left*self == a and a is row
     
    1183111892        if a[k,0] not in I:
    1183211893            try:
    1183311894                v = R.ideal(a[0,0], a[k,0]).gens_reduced()
    11834             except:
    11835                 raise ArithmeticError, "Can't create ideal on %s and %s" % (a[0,0], a[k,0])
     11895            except Exception, msg:
     11896                raise ArithmeticError, "%s\nCan't create ideal on %s and %s" % (msg, a[0,0], a[k,0])
    1183611897            if len(v) > 1:
    1183711898                raise ArithmeticError, "Ideal %s not principal" %  R.ideal(a[0,0], a[k,0])
    1183811899            B = v[0]
  • sage/modules/free_module.py

    diff --git a/sage/modules/free_module.py b/sage/modules/free_module.py
    a b  
    10331033            for a in c:
    10341034                try:
    10351035                    b = R(a)
    1036                 except (TypeError):
     1036                except (TypeError, ValueError):
    10371037                    return False
    10381038                except NotImplementedError:
    10391039                    from sage.rings.all import ZZ
  • 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/all.py

    diff --git a/sage/rings/function_field/__init__.py b/sage/rings/function_field/__init__.py
    new file mode 100644
    diff --git a/sage/rings/function_field/all.py b/sage/rings/function_field/all.py
    new file mode 100644
    - +  
     1from constructor import FunctionField
  • 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
    - +  
     1r"""
     2Factories to construct Function Fields
     3
     4AUTHORS:
     5
     6    - William Stein (2010): initial version
     7
     8    - Maarten Derickx (2011-09-11): added FunctionField_polymod_Constructor, use @cached_function
     9
     10    - Julian Rueth (2011-09-14): replaced @cached_function with UniqueFactory
     11
     12EXAMPLES::
     13
     14    sage: K.<x> = FunctionField(QQ); K
     15    Rational function field in x over Rational Field
     16    sage: L.<x> = FunctionField(QQ); L
     17    Rational function field in x over Rational Field
     18    sage: K is L
     19    True
     20"""
     21#*****************************************************************************
     22#       Copyright (C) 2010 William Stein <wstein@gmail.com>
     23#       Copyright (C) 2011 Maarten Derickx <m.derickx.student@gmail.com>
     24#       Copyright (C) 2011 Julian Rueth <julian.rueth@gmail.com>
     25#
     26#  Distributed under the terms of the GNU General Public License (GPL)
     27#  as published by the Free Software Foundation; either version 2 of
     28#  the License, or (at your option) any later version.
     29#                  http://www.gnu.org/licenses/
     30#*****************************************************************************
     31
     32from sage.structure.factory import UniqueFactory
     33
     34class FunctionFieldFactory(UniqueFactory):
     35    """
     36    Return the function field in one variable with constant field ``F``. The function
     37    field returned is unique in the sense that if you call this function twice
     38    with the same base field and name then you get the same python object back.
     39
     40    INPUT:
     41
     42        - ``F`` -- a field
     43        - ``names`` -- name of variable as a string or a tuple containg a string
     44   
     45    EXAMPLES::
     46
     47        sage: K.<x> = FunctionField(QQ); K
     48        Rational function field in x over Rational Field
     49        sage: L.<y> = FunctionField(GF(7)); L
     50        Rational function field in y over Finite Field of size 7
     51        sage: R.<z> = L[]
     52        sage: M.<z> = L.extension(z^7-z-y); M
     53        Function field in z defined by z^7 + 6*z + 6*y
     54
     55    TESTS::
     56
     57        sage: K.<x> = FunctionField(QQ)
     58        sage: L.<x> = FunctionField(QQ)
     59        sage: K is L
     60        True
     61        sage: M.<x> = FunctionField(GF(7))
     62        sage: K is M
     63        False
     64        sage: N.<y> = FunctionField(QQ)
     65        sage: K is N
     66        False
     67    """
     68    def create_key(self, F, names):
     69        if not isinstance(names,tuple):
     70            names = (names,)
     71        return (F,names)
     72
     73    def create_object(self, version, key, **extra_args):
     74        from function_field import RationalFunctionField
     75        return RationalFunctionField(key[0], names=key[1])
     76
     77FunctionField = FunctionFieldFactory("sage.rings.function_field.constructor.FunctionField")
     78
     79class FunctionFieldPolymodFactory(UniqueFactory):
     80    """
     81    Create a function field defined as an extension of another
     82    function field by adjoining a root of a univariate polynomial.
     83    The returned function field is unique in the sense that if you
     84    call this function twice with an equal ``polynomial`` and ``names``
     85    it returns the same python object in both calls.
     86
     87    INPUT:
     88
     89        - ``polynomial`` -- a univariate polynomial over a function field
     90        - ``names`` -- variable names (as a tuple of length 1 or string)
     91        - ``category`` -- a category (defaults to category of function fields)
     92       
     93    EXAMPLES::
     94
     95        sage: K.<x> = FunctionField(QQ)
     96        sage: R.<y>=K[]
     97        sage: y2 = y*1
     98        sage: y2 is y
     99        False
     100        sage: L.<w>=K.extension(x-y^2) #indirect doctest
     101        sage: M.<w>=K.extension(x-y2^2) #indirect doctest
     102        sage: L is M
     103        True
     104    """
     105    def create_key(self, polynomial, names):
     106        if names is None:
     107            names = polynomial.variable_name()
     108        if not isinstance(names,tuple):
     109            names = (names,)
     110        return (polynomial,names)
     111
     112    def create_object(self, version, key, **extra_args):
     113        from function_field import FunctionField_polymod
     114        return FunctionField_polymod(key[0], names=key[1])
     115
     116FunctionField_polymod = FunctionFieldPolymodFactory("sage.rings.function_field.constructor.FunctionField_polymod")
  • 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
     4AUTHORS:
     5
     6- William Stein (2010): initial version
     7
     8- Robert Bradshaw (2010-05-30): added is_finite()
     9
     10- Julian Rueth (2011-06-08): fixed hom(), extension()
     11
     12- Maarten Derickx (2011-09-11): added doctests
     13
     14- Julian Rueth (2011-09-14): use @cached_method
     15
     16EXAMPLES:
     17
     18We create an extension of a rational function fields, and do some
     19simple arithmetic in it::
     20
     21    sage: K.<x> = FunctionField(GF(5^2,'a')); K
     22    Rational function field in x over Finite Field in a of size 5^2
     23    sage: R.<y> = K[]
     24    sage: L.<y> = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L
     25    Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x
     26    sage: y^2
     27    y^2
     28    sage: y^3
     29    2*x*y + (x^4 + 1)/x
     30    sage: a = 1/y; a
     31    (4*x/(4*x^4 + 4))*y^2 + 2*x^2/(4*x^4 + 4)
     32    sage: a * y
     33    1
     34
     35We next make an extension of the above function field, illustrating
     36that arithmetic with a tower of 3 fields is fully supported::
     37
     38    sage: S.<t> = L[]
     39    sage: M.<t> = L.extension(t^2 - x*y)
     40    sage: M
     41    Function field in t defined by t^2 + 4*x*y
     42    sage: t^2
     43    x*y
     44    sage: 1/t
     45    ((1/(x^4 + 1))*y^2 + 2*x/(4*x^4 + 4))*t
     46    sage: M.base_field()
     47    Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x
     48    sage: M.base_field().base_field()
     49    Rational function field in x over Finite Field in a of size 5^2
     50
     51TESTS::
     52
     53    sage: TestSuite(K).run() #long time
     54    sage: TestSuite(L).run() #long time
     55    sage: TestSuite(M).run() #long time
     56 
     57The following two test suites do not pass ``_test_elements`` yet since
     58``R.an_element()`` has a ``_test_category`` method wich it should not have.
     59It is not the fault of the function field code so this will
     60be fixed in another ticket::
     61
     62    sage: TestSuite(R).run(skip = '_test_elements') #long time
     63    sage: TestSuite(S).run(skip = '_test_elements') #long time
     64"""
     65#*****************************************************************************
     66#       Copyright (C) 2010 William Stein <wstein@gmail.com>
     67#       Copyright (C) 2010 Robert Bradshaw <robertwb@math.washington.edu>
     68#       Copyright (C) 2011 Julian Rueth <julian.rueth@gmail.com>
     69#       Copyright (C) 2011 Maarten Derickx <m.derickx.student@gmail.com>
     70#
     71#  Distributed under the terms of the GNU General Public License (GPL)
     72#  as published by the Free Software Foundation; either version 2 of
     73#  the License, or (at your option) any later version.
     74#                  http://www.gnu.org/licenses/
     75#*****************************************************************************
     76
     77from sage.rings.ring import Field
     78from function_field_element import FunctionFieldElement, FunctionFieldElement_rational, FunctionFieldElement_polymod
     79
     80from sage.misc.cachefunc import cached_method
     81
     82from sage.categories.function_fields import FunctionFields
     83CAT = FunctionFields()
     84
     85def is_FunctionField(x):
     86    """
     87    Return True if ``x`` is of function field type.
     88
     89    EXAMPLES::
     90   
     91        sage: from sage.rings.function_field.function_field import is_FunctionField
     92        sage: is_FunctionField(QQ)
     93        False
     94        sage: is_FunctionField(FunctionField(QQ,'t'))
     95        True
     96    """
     97    if isinstance(x, FunctionField): return True
     98    return x in FunctionFields()
     99
     100class FunctionField(Field):
     101    """
     102    The abstract base class for all function fields.
     103   
     104    EXAMPLES::
     105   
     106        sage: K.<x> = FunctionField(QQ)
     107        sage: isinstance(K, sage.rings.function_field.function_field.FunctionField)
     108        True
     109    """
     110    def some_elements(self):
     111         """
     112         Return a list of elements in the function field.
     113
     114         EXAMPLES::
     115
     116            sage: K.<x> = FunctionField(QQ)
     117            sage: elements = K.some_elements()
     118            sage: elements # random output
     119            [(x - 3/2)/(x^2 - 12/5*x + 1/18)]
     120            sage: False in [e in K for e in elements]
     121            False
     122         """
     123         return [self.random_element(), self.random_element(), self.random_element()]
     124
     125    def characteristic(self):
     126        """
     127        Return the characteristic of this function field.
     128
     129        EXAMPLES::
     130
     131            sage: R.<t> = FunctionField(QQ)
     132            sage: R.characteristic()
     133            0
     134            sage: R.<t> = FunctionField(GF(7))
     135            sage: R.characteristic()
     136            7
     137        """
     138        return self.constant_field().characteristic()
     139   
     140    def is_finite(self):
     141        """
     142        Return whether this function field is finite, which it is not.
     143
     144        EXAMPLES::
     145
     146            sage: R.<t> = FunctionField(QQ)
     147            sage: R.is_finite()
     148            False
     149            sage: R.<t> = FunctionField(GF(7))
     150            sage: R.is_finite()
     151            False
     152        """
     153        return False
     154   
     155    def extension(self, f, names=None):
     156        """
     157        Create an extension L = K[y]/(f(y)) of a function field,
     158        defined by a univariate polynomial in one variable over this
     159        function field K.
     160
     161        INPUT:
     162       
     163            - ``f`` -- a univariate polynomial over self
     164            - ``names`` -- None or string or length-1 tuple
     165
     166        OUTPUT:
     167
     168            - a function field
     169       
     170        EXAMPLES::
     171       
     172            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     173            sage: K.extension(y^5 - x^3 - 3*x + x*y)
     174            Function field in y defined by y^5 + x*y - x^3 - 3*x
     175
     176        A nonintegral defining polynomial::
     177
     178            sage: K.<t> = FunctionField(QQ); R.<y> = K[]
     179            sage: K.extension(y^3 + (1/t)*y + t^3/(t+1))
     180            Function field in y defined by y^3 + 1/t*y + t^3/(t + 1)
     181
     182        The defining polynomial need not be monic or integral::
     183
     184            sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1))
     185            Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1)
     186        """
     187        from constructor import FunctionField_polymod as FunctionField_polymod_Constructor
     188        return FunctionField_polymod_Constructor(f, names)
     189
     190    def order_with_basis(self, basis, check=True):
     191        """
     192        Return the order with given basis over the maximal order of
     193        the base field.
     194
     195        INPUT:
     196
     197           - ``basis`` -- a list of elements of self
     198           - ``check`` -- bool (default: True); if True, check that
     199             the basis is really linearly independent and that the
     200             module it spans is closed under multiplication, and
     201             contains the identity element.
     202
     203        OUTPUT:
     204
     205            - an order in this function field
     206
     207        EXAMPLES::
     208
     209            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<y> = K.extension(y^3 + x^3 + 4*x + 1)
     210            sage: O = L.order_with_basis([1, y, y^2]); O
     211            Order in Function field in y defined by y^3 + x^3 + 4*x + 1
     212            sage: O.basis()
     213            (1, y, y^2)
     214
     215        Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it::
     216
     217            sage: O = L.order_with_basis([1+y, y, y^2]); O
     218            Order in Function field in y defined by y^3 + x^3 + 4*x + 1
     219            sage: O.basis()
     220            (y + 1, y, y^2)
     221       
     222        The following error is raised when the module spanned by the basis is not closed under multiplication::
     223
     224            sage: O = L.order_with_basis([1, x^2 + x*y, (2/3)*y^2]); O
     225            Traceback (most recent call last):
     226            ...
     227            ValueError: The module generated by basis [1, x*y + x^2, 2/3*y^2] must be closed under multiplication
     228           
     229        and this happens when the identity is not in the module spanned by the basis::
     230
     231            sage: O = L.order_with_basis([x, x^2 + x*y, (2/3)*y^2])
     232            Traceback (most recent call last):
     233            ...
     234            ValueError: The identity element must be in the module spanned by basis [x, x*y + x^2, 2/3*y^2]
     235        """
     236        from function_field_order import FunctionFieldOrder_basis
     237        return FunctionFieldOrder_basis([self(a) for a in basis], check=check)
     238
     239    def order(self, x, check=True):
     240        """
     241        Return the order in this function field generated over the
     242        maximal order by x or the elements of x if x is a list.
     243
     244        INPUT:
     245       
     246           - ``x`` -- element of self, or a list of elements of self
     247           - ``check`` -- bool (default: True); if True, check that
     248             x really generates an order
     249
     250        EXAMPLES::
     251
     252            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<y> = K.extension(y^3 + x^3 + 4*x + 1)
     253            sage: O = L.order(y); O
     254            Order in Function field in y defined by y^3 + x^3 + 4*x + 1
     255            sage: O.basis()
     256            (1, y, y^2)
     257
     258            sage: Z = K.order(x); Z
     259            Order in Rational function field in x over Rational Field
     260            sage: Z.basis()
     261            (1,)
     262
     263        Orders with multiple generators, not yet supported::
     264
     265            sage: Z = K.order([x,x^2]); Z
     266            Traceback (most recent call last):
     267            ...
     268            NotImplementedError
     269        """
     270        if not isinstance(x, (list, tuple)):
     271            x = [x]
     272        if len(x) == 1:
     273            g = x[0]
     274            basis = [self(1)]
     275            for i in range(self.degree()-1):
     276                basis.append(basis[-1]*g)
     277        else:
     278            raise NotImplementedError
     279        return self.order_with_basis(basis, check=check)
     280
     281    def _coerce_map_from_(self, R):
     282        """
     283        Return True if there is a coerce map from R to self.
     284
     285        EXAMPLES::
     286
     287            sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<y> = K.extension(y^3 + x^3 + 4*x + 1)
     288            sage: L.equation_order()
     289            Order in Function field in y defined by y^3 + x^3 + 4*x + 1
     290            sage: L._coerce_map_from_(L.equation_order())
     291            True
     292            sage: L._coerce_map_from_(GF(7))
     293            False
     294        """
     295        from function_field_order import FunctionFieldOrder
     296        if isinstance(R, FunctionFieldOrder) and R.fraction_field() == self:
     297            return True
     298        return False
     299
     300class FunctionField_polymod(FunctionField):
     301    """
     302    A function field defined by a univariate polynomial, as an
     303    extension of the base field.
     304   
     305    EXAMPLES:
     306
     307    We make a function field defined by a degree 5 polynomial over the
     308    rational function field over the rational numbers::
     309   
     310        sage: K.<x> = FunctionField(QQ)
     311        sage: R.<y> = K[]
     312        sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     313        Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     314
     315    We next make a function field over the above nontrivial function
     316    field L::
     317
     318        sage: S.<z> = L[]
     319        sage: M.<z> = L.extension(z^2 + y*z + y); M
     320        Function field in z defined by z^2 + y*z + y
     321        sage: 1/z
     322        ((x/(-x^4 - 1))*y^4 - 2*x^2/(-x^4 - 1))*z - 1
     323        sage: z * (1/z)
     324        1
     325
     326    We drill down the tower of function fields::
     327   
     328        sage: M.base_field()
     329        Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     330        sage: M.base_field().base_field()
     331        Rational function field in x over Rational Field
     332        sage: M.base_field().base_field().constant_field()
     333        Rational Field
     334        sage: M.constant_base_field()
     335        Rational Field
     336
     337    .. WARNING::
     338
     339        It is not checked if the polynomial used to define this function field is irreducible
     340        Hence it is not guaranteed that this object really is a field!
     341        This is illustrated below.
     342
     343    ::
     344
     345        sage: K.<x>=FunctionField(QQ)
     346        sage: R.<y> = K[]
     347        sage: L.<y>=K.extension(x^2-y^2)
     348        sage: (y-x)*(y+x)
     349        0
     350        sage: 1/(y-x)
     351        1
     352        sage: y-x==0; y+x==0
     353        False
     354        False
     355    """
     356    def __init__(self, polynomial, names,
     357            element_class = FunctionFieldElement_polymod,
     358            category=CAT):
     359        """
     360        Create a function field defined as an extension of another
     361        function field by adjoining a root of a univariate polynomial.
     362
     363        INPUT:
     364
     365            - ``polynomial`` -- a univariate polynomial over a function field
     366            - ``names`` -- variable names (as a tuple of length 1 or string)
     367            - ``category`` -- a category (defaults to category of function fields)
     368       
     369        EXAMPLES::
     370
     371        We create an extension of a function field::
     372       
     373            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     374            sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L
     375            Function field in y defined by y^5 + x*y - x^3 - 3*x
     376
     377        Note the type::
     378       
     379            sage: type(L)
     380            <class 'sage.rings.function_field.function_field.FunctionField_polymod_with_category'>
     381
     382        We can set the variable name, which doesn't have to be y::
     383       
     384            sage: L.<w> = K.extension(y^5 - x^3 - 3*x + x*y); L
     385            Function field in w defined by y^5 + x*y - x^3 - 3*x
     386        """
     387        from sage.rings.polynomial.all import is_Polynomial
     388        if polynomial.parent().ngens()>1 or not is_Polynomial(polynomial):
     389            raise TypeError, "polynomial must be univariate a polynomial"
     390        if names is None:
     391            names = (polynomial.variable_name(), )
     392        if polynomial.degree() <= 0:
     393            raise ValueError, "polynomial must have positive degree"
     394        base_field = polynomial.base_ring()
     395        if not isinstance(base_field, FunctionField):
     396            raise TypeError, "polynomial must be over a FunctionField"
     397        self._element_class = element_class
     398        self._element_init_pass_parent = False
     399        self._base_field = base_field
     400        self._polynomial = polynomial
     401       
     402        Field.__init__(self, base_field,
     403                                names=names, category = category)
     404
     405        self._hash = hash(polynomial)
     406        self._ring = self._polynomial.parent()
     407        self._populate_coercion_lists_(coerce_list=[base_field, self._ring])
     408        self._gen = self(self._ring.gen())
     409
     410    def __reduce__(self):
     411        """
     412        Returns the arguments which were used to create this instance. The rationale for this is explained in the documentation of ``UniqueRepresentation``.
     413
     414        EXAMPLES::
     415
     416            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     417            sage: L = K.extension(y^2-x)
     418            sage: clazz,args = L.__reduce__()
     419            sage: clazz(*args)
     420            Function field in y defined by y^2 - x
     421        """
     422        from constructor import FunctionField_polymod as FunctionField_polymod_Constructor
     423        return  FunctionField_polymod_Constructor, (self._polynomial, self._names)
     424
     425    def __hash__(self):
     426        """
     427        Return hash of this function field.
     428       
     429        EXAMPLES::
     430
     431            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     432            sage: L = K.extension(y^5 - x^3 - 3*x + x*y); hash(L)
     433            3183366741743088279             # 64-bit
     434            2003022487                      # 32-bit
     435        """
     436        return self._hash
     437
     438    def monic_integral_model(self, names):
     439        """
     440        Return a function field isomorphic to self, but with defining
     441        polynomial that is monic and integral over the base field.
     442
     443        INPUT:
     444
     445            - ``names`` -- name of the generator of the new field this function constructs
     446
     447        EXAMPLES::
     448
     449            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     450            sage: L.<y> = K.extension(x^2*y^5 - 1/x); L
     451            Function field in y defined by x^2*y^5 - 1/x
     452            sage: A, from_A, to_A = L.monic_integral_model('z')
     453            sage: A
     454            Function field in z defined by y^5 - x^12
     455            sage: from_A
     456            Morphism of function fields defined by z |--> x^3*y
     457            sage: to_A
     458            Morphism of function fields defined by y |--> 1/x^3*z
     459            sage: to_A(y)
     460            1/x^3*z
     461            sage: from_A(to_A(y))
     462            y
     463            sage: from_A(to_A(1/y))
     464            x^3*y^4
     465            sage: from_A(to_A(1/y)) == 1/y
     466            True
     467        """
     468        g, d = self._make_monic_integral(self.polynomial())
     469        R = self.base_field()
     470        K = R.extension(g, names=names)
     471        to_K = self.hom(K.gen() / d)
     472        from_K = K.hom(self.gen() * d)
     473        return K, from_K, to_K
     474
     475    def _make_monic_integral(self, f):
     476        r"""
     477        Let y be a root of ``f``.  This function returns a monic
     478        integral polynomial g and an element d of the base field such
     479        that g(y*d)=0.
     480       
     481        EXAMPLES::
     482       
     483            sage: K.<x> = FunctionField(QQ); R.<y> = K[];
     484            sage: L.<y> = K.extension(x^2*y^5 - 1/x)
     485            sage: g, d = L._make_monic_integral(L.polynomial()); g,d
     486            (y^5 - x^12, x^3)
     487            sage: (y*d).is_integral()
     488            True
     489            sage: g.is_monic()
     490            True
     491            sage: g(y*d)
     492            0
     493        """
     494        R = f.base_ring()
     495        if not isinstance(R, RationalFunctionField):
     496            raise NotImplementedError
     497       
     498        # make f monic
     499        n = f.degree()
     500        c = f.leading_coefficient()
     501        if c != 1:
     502            f = f / c
     503
     504        # find lcm of denominators
     505        from sage.rings.arith import lcm
     506        # would be good to replace this by minimal...
     507        d = lcm([b.denominator() for b in f.list() if b])
     508        if d != 1:
     509            x = f.parent().gen()
     510            g = (d**n) * f(x/d)
     511        else:
     512            g = f
     513        return g, d
     514
     515    def constant_field(self):
     516        """
     517        Return the algebraic closure of the constant field of the base
     518        field in this function field.
     519
     520        EXAMPLES::
     521
     522            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     523            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     524            sage: L.constant_field()
     525            Traceback (most recent call last):
     526            ...
     527            NotImplementedError
     528        """
     529        raise NotImplementedError
     530
     531    def constant_base_field(self):
     532        """
     533        Return the constant field of the base rational function field.
     534                   
     535        EXAMPLES::
     536
     537            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     538            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     539            Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     540            sage: L.constant_base_field()
     541            Rational Field
     542            sage: S.<z> = L[]
     543            sage: M.<z> = L.extension(z^2 - y)
     544            sage: M.constant_base_field()
     545            Rational Field
     546        """
     547        return self.base_field().constant_base_field()
     548
     549    def degree(self):
     550        """
     551        Return the degree of this function field over its base
     552        function field.
     553       
     554        EXAMPLES::
     555
     556            sage: K.<x> = FunctionField(QQ)
     557            sage: R.<y> = K[]
     558            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     559            Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     560            sage: L.degree()
     561            5
     562        """
     563        return self._polynomial.degree()
     564       
     565    def _repr_(self):
     566        """
     567        Return string representation of this function field.
     568       
     569        EXAMPLES::
     570
     571            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     572            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     573            sage: L._repr_()
     574            'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x'
     575        """
     576        return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial)
     577
     578    def base_field(self):
     579        """
     580        Return the base field of this function field.  This function
     581        field is presented as L = K[y]/(f(y)), and the base field is
     582        by definition the field K.
     583       
     584        EXAMPLES::
     585
     586            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     587            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     588            sage: L.base_field()
     589            Rational function field in x over Rational Field
     590        """
     591        return self._base_field
     592
     593    def random_element(self, *args, **kwds):
     594        """
     595        Create a random element of this function field.  Parameters
     596        are passed onto the random_element method of the base_field.
     597
     598        EXAMPLES::
     599
     600            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     601            sage: L.<y> = K.extension(y^2 - (x^2 + x))
     602            sage: L.random_element() # random
     603            ((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95)
     604        """
     605        return self(self._ring.random_element(degree=self.degree(), *args, **kwds))
     606
     607    def polynomial(self):
     608        """
     609        Return the univariate polynomial that defines this function
     610        field, i.e., the polynomial f(y) so that this function field
     611        is of the form K[y]/(f(y)).
     612       
     613        EXAMPLES::
     614
     615            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     616            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     617            sage: L.polynomial()
     618            y^5 - 2*x*y + (-x^4 - 1)/x
     619        """
     620        return self._polynomial
     621
     622    def polynomial_ring(self):
     623        """
     624        Return the polynomial ring used to represent elements of this
     625        function field.  If we view this function field as being presented
     626        as K[y]/(f(y)), then this function returns the ring K[y].
     627       
     628        EXAMPLES::
     629
     630            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     631            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     632            sage: L.polynomial_ring()
     633            Univariate Polynomial Ring in y over Rational function field in x over Rational Field
     634        """
     635        return self._ring
     636
     637    @cached_method
     638    def vector_space(self):
     639        """
     640        Return a vector space V and isomorphisms self --> V and V --> self.
     641
     642        This function allows us to identify the elements of self with
     643        elements of a vector space over the base field, which is
     644        useful for representation and arithmetic with orders, ideals,
     645        etc.
     646       
     647        OUTPUT:
     648
     649            -  ``V`` -- a vector space over base field
     650            -  ``from_V`` -- an isomorphism from V to self
     651            -  ``to_V`` -- an isomorphism from self to V
     652
     653        EXAMPLES:
     654
     655        We define a function field::
     656       
     657            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     658            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
     659            Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     660
     661        We get the vector spaces, and maps back and forth::
     662       
     663            sage: V, from_V, to_V = L.vector_space()
     664            sage: V
     665            Vector space of dimension 5 over Rational function field in x over Rational Field
     666            sage: from_V
     667            Isomorphism morphism:
     668              From: Vector space of dimension 5 over Rational function field in x over Rational Field
     669              To:   Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     670            sage: to_V
     671            Isomorphism morphism:
     672              From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     673              To:   Vector space of dimension 5 over Rational function field in x over Rational Field
     674
     675        We convert an element of the vector space back to the function field::
     676       
     677            sage: from_V(V.1)
     678            y
     679
     680        We define an interesting element of the function field::
     681       
     682            sage: a = 1/L.0; a
     683            (-x/(-x^4 - 1))*y^4 + 2*x^2/(-x^4 - 1)
     684
     685        We convert it to the vector space, and get a vector over the base field::
     686       
     687            sage: to_V(a)
     688            (2*x^2/(-x^4 - 1), 0, 0, 0, -x/(-x^4 - 1))
     689
     690        We convert to and back, and get the same element::
     691       
     692            sage: from_V(to_V(a)) == a
     693            True
     694
     695        In the other direction::
     696
     697            sage: v = x*V.0 + (1/x)*V.1
     698            sage: to_V(from_V(v)) == v
     699            True
     700
     701        And we show how it works over an extension of an extension field::
     702
     703            sage: R2.<z> = L[]; M.<z> = L.extension(z^2 -y)
     704            sage: M.vector_space()
     705            (Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism morphism:
     706              From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
     707              To:   Function field in z defined by z^2 - y, Isomorphism morphism:
     708              From: Function field in z defined by z^2 - y
     709              To:   Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x)
     710        """
     711        V = self.base_field()**self.degree()
     712        from maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace
     713        from_V = MapVectorSpaceToFunctionField(V, self)
     714        to_V   = MapFunctionFieldToVectorSpace(self, V)
     715        return (V, from_V, to_V)
     716       
     717    def maximal_order(self):
     718        """
     719        Return the maximal_order of self.  If we view self as L =
     720        K[y]/(f(y)), then this is the ring of elements of L that are
     721        integral over K.
     722       
     723        EXAMPLES:
     724
     725        This is not yet implemented...::
     726       
     727            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     728            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     729            sage: L.maximal_order()
     730            Traceback (most recent call last):
     731            ...
     732            NotImplementedError
     733        """
     734        raise NotImplementedError
     735
     736    def _element_constructor_(self, x):
     737        r"""
     738        Make ``x`` into an element of this function field, possibly not canonically.
     739
     740        INPUT:
     741       
     742            - ``x`` -- the element
     743         
     744        OUTPUT:
     745       
     746            ``x``, as an element of this function field
     747
     748        TESTS::
     749
     750            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     751            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     752            sage: L._element_constructor_(L.polynomial_ring().gen())
     753            y
     754        """
     755        if x.parent() is self._ring:
     756            return FunctionFieldElement_polymod(self, x)
     757        if isinstance(x, FunctionFieldElement):
     758            return FunctionFieldElement_polymod(self, self._ring(x.element()))
     759        return FunctionFieldElement_polymod(self, self._ring(x))
     760
     761    def gen(self, n=0):
     762        """
     763        Return the ``n``-th generator of this function field. By default ``n`` is 0; any other
     764        value of ``n`` leads to an error. The generator is the class of y, if we view
     765        self as being presented as K[y]/(f(y)).
     766       
     767        EXAMPLES::
     768
     769            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     770            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     771            sage: L.gen()
     772            y
     773            sage: L.gen(1)
     774            Traceback (most recent call last):
     775            ...
     776            IndexError: Only one generator.
     777        """
     778        if n != 0: raise IndexError, "Only one generator."
     779        return self._gen
     780
     781    def ngens(self):
     782        """
     783        Return the number of generators of this function field over
     784        its base field.  This is by definition 1.
     785       
     786        EXAMPLES::
     787       
     788            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     789            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     790            sage: L.ngens()
     791            1
     792        """
     793        return 1
     794
     795    def equation_order(self):
     796        """
     797        If we view self as being presented as K[y]/(f(y)), then this
     798        function returns the order generated by the class of y.  If f
     799        is not monic, then :meth:`_make_monic_integral` is called, and instead we
     800        get the order generated by some integral multiple of a root of f.
     801       
     802        EXAMPLES::
     803
     804            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     805            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     806            sage: O = L.equation_order()
     807            sage: O.basis()
     808            (1, x*y, x^2*y^2, x^3*y^3, x^4*y^4)
     809
     810        We try an example, in which the defining polynomial is not
     811        monic and is not integral::
     812
     813            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     814            sage: L.<y> = K.extension(x^2*y^5 - 1/x); L
     815            Function field in y defined by x^2*y^5 - 1/x
     816            sage: O = L.equation_order()
     817            sage: O.basis()
     818            (1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4)
     819        """
     820        d = self._make_monic_integral(self.polynomial())[1]
     821        return self.order(d*self.gen(), check=False)
     822
     823    def hom(self, im_gens, base_morphism=None):
     824        """
     825        Create a homomorphism from self to another function field.
     826
     827        INPUT:
     828
     829           - ``im_gens`` -- a list of images of the generators of self
     830             and of successive base rings.
     831
     832           - ``base_morphism`` -- (default: None) a homomorphism of
     833             the base ring, after the im_gens are used.  Thus if
     834             im_gens has length 2, then base_morphism should be a morphism
     835             from self.base_ring().base_ring().
     836
     837        EXAMPLES:
     838
     839        We create a rational function field, and a quadratic extension of it::
     840
     841            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     842            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     843
     844        We make the field automorphism that sends y to -y::
     845
     846            sage: f = L.hom(-y); f
     847            Morphism of function fields defined by y |--> -y
     848
     849        Evaluation works::
     850
     851            sage: f(y*x - 1/x)
     852            -x*y - 1/x
     853
     854        We try to define an invalid morphism::
     855
     856            sage: f = L.hom(y+1)
     857            Traceback (most recent call last):
     858            ...
     859            ValueError: invalid morphism
     860
     861        We make a morphism of the base rational function field::
     862
     863            sage: phi = K.hom(x+1); phi
     864            Morphism of function fields defined by x |--> x + 1
     865            sage: phi(x^3 - 3)
     866            x^3 + 3*x^2 + 3*x - 2
     867            sage: (x+1)^3-3
     868            x^3 + 3*x^2 + 3*x - 2
     869
     870        We make a morphism by specifying where the generators and the
     871        base generators go::
     872
     873            sage: L.hom([-y, x])
     874            Morphism of function fields defined by y |--> -y,  x |--> x
     875
     876        The usage of the keyword base_morphism is not implemented yet::
     877
     878            sage: L.hom([-y, x-1], base_morphism=phi)
     879            Traceback (most recent call last):
     880            ...
     881            NotImplementedError: Function field homorphisms with optional argument base_morphism are not implemented yet. Please specify the images of the generators of the base fields manually.
     882
     883        We make another extension of a rational function field::
     884
     885            sage: K2.<t> = FunctionField(QQ); R2.<w> = K2[]
     886            sage: L2.<w> = K2.extension((4*w)^2 - (t+1)^3 - 1)
     887
     888        We define a morphism, by giving the images of generators::
     889
     890            sage: f = L.hom([4*w, t+1]); f
     891            Morphism of function fields defined by y |--> 4*w,  x |--> t + 1
     892
     893        Evaluation works, as expected::
     894
     895            sage: f(y+x)
     896            4*w + t + 1
     897            sage: f(x*y + x/(x^2+1))
     898            (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2)
     899
     900        We make another extension of a rational function field::
     901
     902            sage: K3.<yy> = FunctionField(QQ); R3.<xx> = K3[]
     903            sage: L3.<xx> = K3.extension(yy^2 - xx^3 - 1)
     904
     905        This is the function field L with the generators exchanged. We define a morphism to L::
     906
     907            sage: g = L3.hom([x,y]); g
     908            Morphism of function fields defined by xx |--> x, yy |--> y
     909        """
     910        if base_morphism is not None:
     911            raise NotImplementedError, "Function field homorphisms with optional argument base_morphism are not implemented yet. Please specify the images of the generators of the base fields manually."
     912
     913        if not isinstance(im_gens, (list,tuple)):
     914            im_gens = [im_gens]
     915        if len(im_gens) == 0:
     916            raise ValueError, "no images specified"
     917
     918        if len(im_gens) > 1:
     919            base_morphism = self.base_field().hom(im_gens[1:], base_morphism)
     920
     921        # the codomain of this morphism is the field containing all the im_gens
     922        codomain = im_gens[0].parent();
     923        if base_morphism is not None:
     924            if base_morphism.codomain().has_coerce_map_from(codomain):
     925                codomain = base_morphism.codomain();
     926
     927        from maps import FunctionFieldMorphism_polymod
     928        return FunctionFieldMorphism_polymod(self.Hom(codomain), im_gens[0], base_morphism)
     929
     930class RationalFunctionField(FunctionField):
     931    """
     932    A rational function field K(t) in one variable, over an arbitrary
     933    base field.
     934   
     935    EXAMPLES::
     936
     937        sage: K.<t> = FunctionField(GF(3)); K
     938        Rational function field in t over Finite Field of size 3
     939        sage: K.gen()
     940        t
     941        sage: 1/t + t^3 + 5
     942        (t^4 + 2*t + 1)/t
     943
     944    There are various ways to get at the underlying fields and rings
     945    associated to a rational function field::
     946
     947        sage: K.<t> = FunctionField(GF(7))
     948        sage: K.base_field()
     949        Rational function field in t over Finite Field of size 7
     950        sage: K.field()
     951        Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     952        sage: K.constant_field()
     953        Finite Field of size 7
     954        sage: K.maximal_order()
     955        Maximal order in Rational function field in t over Finite Field of size 7
     956
     957    We define a morphism::
     958
     959        sage: K.<t> = FunctionField(QQ)
     960        sage: L = FunctionField(QQ, 'tbar') # give variable name as second input
     961        sage: K.hom(L.gen())
     962        Morphism of function fields defined by t |--> tbar
     963    """
     964    def __init__(self, constant_field, names,
     965            element_class = FunctionFieldElement_rational,
     966            category=CAT):
     967        """
     968        Create a rational function field in one variable.
     969
     970        INPUT:
     971
     972            - ``constant_field`` -- an arbitrary field
     973            - ``names`` -- a string or tuple of length 1
     974            - ``category`` -- default: FunctionFields()
     975       
     976        EXAMPLES::
     977
     978            sage: K.<t> = FunctionField(CC); K
     979            Rational function field in t over Complex Field with 53 bits of precision
     980            sage: K.category()
     981            Category of function fields
     982            sage: FunctionField(QQ[I], 'alpha')
     983            Rational function field in alpha over Number Field in I with defining polynomial x^2 + 1
     984
     985        Must be over a field::
     986       
     987            sage: FunctionField(ZZ, 't')
     988            Traceback (most recent call last):
     989            ...
     990            TypeError: constant_field must be a field
     991        """
     992        if names is None:
     993            raise ValueError, "variable name must be specified"
     994        elif not isinstance(names, tuple):
     995            names = (names, )
     996        if not constant_field.is_field():
     997            raise TypeError, "constant_field must be a field"
     998        self._element_class = element_class
     999        self._element_init_pass_parent = False
     1000        Field.__init__(self, self, names=names, category = category)
     1001        R = constant_field[names[0]]
     1002        self._hash = hash((constant_field, names))
     1003        self._constant_field = constant_field
     1004        self._ring = R
     1005        self._field = R.fraction_field()
     1006        self._populate_coercion_lists_(coerce_list=[self._field])
     1007        self._gen = self(R.gen())
     1008
     1009    def __reduce__(self):
     1010        """
     1011        Returns the arguments which were used to create this instance. The rationale for this is explained in the documentation of ``UniqueRepresentation``.
     1012
     1013        EXAMPLES::
     1014
     1015            sage: K.<x> = FunctionField(QQ)
     1016            sage: clazz,args = K.__reduce__()
     1017            sage: clazz(*args)
     1018            Rational function field in x over Rational Field
     1019        """
     1020        from constructor import FunctionField
     1021        return FunctionField, (self._constant_field, self._names)
     1022   
     1023    def __hash__(self):
     1024        """
     1025        Return hash of this function field.
     1026
     1027        EXAMPLES::
     1028       
     1029            sage: K.<t> = FunctionField(QQ)
     1030            sage: hash(K)
     1031            502145503910697533              # 64-bit
     1032            -500688323                      # 32-bit
     1033        """
     1034        return self._hash
     1035
     1036    def _repr_(self):
     1037        """
     1038        Return string representation of this function field.
     1039       
     1040        EXAMPLES::
     1041       
     1042            sage: K.<t> = FunctionField(QQ)
     1043            sage: K._repr_()
     1044            'Rational function field in t over Rational Field'
     1045        """
     1046        return "Rational function field in %s over %s"%(
     1047            self.variable_name(), self._constant_field)
     1048
     1049    def _element_constructor_(self, x):
     1050        r"""
     1051        Coerce ``x`` into an element of this function field, possibly not canonically.
     1052
     1053        INPUT:
     1054       
     1055            - ``x`` -- the element
     1056         
     1057        OUTPUT:
     1058       
     1059            ``x``, as an element of this function field
     1060
     1061        EXAMPLES::
     1062       
     1063            sage: K.<t> = FunctionField(QQ)
     1064            sage: a = K._element_constructor_(K.maximal_order().gen()); a
     1065            t
     1066            sage: a.parent()
     1067            Rational function field in t over Rational Field
     1068       
     1069        """
     1070        if x.parent() is self._field:
     1071            return FunctionFieldElement_rational(self, x)
     1072        if isinstance(x, FunctionFieldElement):
     1073            return FunctionFieldElement_rational(self, self._field(x.element()))
     1074        if x.parent() is self.polynomial_ring():
     1075            return x[0]
     1076        return FunctionFieldElement_rational(self, self._field(x))
     1077
     1078    def _to_bivariate_polynomial(self, f):
     1079        """
     1080        Convert ``f`` from a univariate polynomial over the rational function
     1081        field into a bivariate polynomial and a denominator.
     1082
     1083        INPUT:
     1084
     1085            - ``f`` -- a univariate polynomial over self.
     1086
     1087        OUTPUT:
     1088
     1089            - bivariate polynomial, denominator
     1090
     1091        EXAMPLES::
     1092       
     1093            sage: R.<t> = FunctionField(GF(7))
     1094            sage: S.<X> = R[]
     1095            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     1096            sage: R._to_bivariate_polynomial(f)
     1097            (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3)       
     1098        """
     1099        v = f.list()
     1100        from sage.rings.arith import LCM
     1101        denom = LCM([a.denominator() for a in v])
     1102        S = denom.parent()
     1103        x,t = S.base_ring()['%s,%s'%(f.parent().variable_name(),self.variable_name())].gens()
     1104        phi = S.hom([t])
     1105        return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom
     1106
     1107    def _factor_univariate_polynomial(self, f, proof=True):
     1108        """
     1109        Factor the univariate polynomial ``f`` over self.
     1110
     1111        EXAMPLES::
     1112
     1113        We do a factorization over the function field over the rationals::
     1114
     1115            sage: R.<t> = FunctionField(QQ)
     1116            sage: S.<X> = R[]
     1117            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     1118            sage: f.factor()             # indirect doctest
     1119            (1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2)
     1120            sage: f.factor().prod() == f
     1121            True
     1122
     1123        You must pass in ``proof=False`` over finite fields, due to
     1124        Singular's factoring algorithm being incomplete::
     1125
     1126            sage: R.<t> = FunctionField(GF(7))
     1127            sage: S.<X> = R[]
     1128            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
     1129            sage: f.factor()
     1130            Traceback (most recent call last):
     1131            ...
     1132            NotImplementedError: proof = True factorization not implemented.  Call factor with proof=False.
     1133            sage: f.factor(proof=False)
     1134            (1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t)
     1135            sage: f.factor(proof=False).prod() == f
     1136            True
     1137
     1138        Factoring over a function field over a non-prime finite field::
     1139
     1140            sage: k.<a> = GF(9)
     1141            sage: R.<t> = FunctionField(k)
     1142            sage: S.<X> = R[]
     1143            sage: f = (1/t)*(X^3 - a*t^3)
     1144            sage: f.factor(proof=False)
     1145            (1/t) * (X + (a + 2)*t)^3
     1146            sage: f.factor(proof=False).prod() == f
     1147            True
     1148        """
     1149        F, d = self._to_bivariate_polynomial(f)
     1150        fac = F.factor(proof=proof)
     1151        x = f.parent().gen()
     1152        t = f.parent().base_ring().gen()
     1153        phi = F.parent().hom([x, t])
     1154        v = [(phi(P),e) for P, e in fac]
     1155        unit = phi(fac.unit())/d
     1156        w = []
     1157        for a, e in v:
     1158            c = a.leading_coefficient()
     1159            a = a/c
     1160            unit *= (c**e)
     1161            w.append((a,e))
     1162        from sage.structure.factorization import Factorization
     1163        return Factorization(w, unit=unit)
     1164
     1165    @cached_method
     1166    def polynomial_ring(self, var='x'):
     1167        """
     1168        Return a polynomial ring in one variable over this rational function field.
     1169       
     1170        INPUT:
     1171
     1172            - ``var`` -- a string (default: 'x')
     1173
     1174        EXAMPLES::
     1175       
     1176            sage: K.<x> = FunctionField(QQ)
     1177            sage: K.polynomial_ring()
     1178            Univariate Polynomial Ring in x over Rational function field in x over Rational Field
     1179            sage: K.polynomial_ring('T')
     1180            Univariate Polynomial Ring in T over Rational function field in x over Rational Field
     1181        """
     1182        return self[var]
     1183
     1184    @cached_method
     1185    def vector_space(self):
     1186        """
     1187        Return a vector space V and isomorphisms self --> V and V --> self.
     1188       
     1189        OUTPUT:
     1190
     1191            -  ``V`` -- a vector space over the rational numbers
     1192            -  ``from_V`` -- an isomorphism from V to self
     1193            -  ``to_V`` -- an isomorphism from self to V
     1194
     1195        EXAMPLES::
     1196
     1197            sage: K.<x> = FunctionField(QQ)
     1198            sage: K.vector_space()
     1199            (Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism morphism:
     1200              From: Vector space of dimension 1 over Rational function field in x over Rational Field
     1201              To:   Rational function field in x over Rational Field, Isomorphism morphism:
     1202              From: Rational function field in x over Rational Field
     1203              To:   Vector space of dimension 1 over Rational function field in x over Rational Field)
     1204        """
     1205        V = self.base_field()**1
     1206        from maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace
     1207        from_V = MapVectorSpaceToFunctionField(V, self)
     1208        to_V   = MapFunctionFieldToVectorSpace(self, V)
     1209        return (V, from_V, to_V)
     1210
     1211    def random_element(self, *args, **kwds):
     1212        """
     1213        Create a random element of this rational function field.
     1214        Parameters are passed onto the random_element method of the
     1215        underlying fraction field.
     1216
     1217        EXAMPLES::
     1218
     1219            sage: FunctionField(QQ,'alpha').random_element()
     1220            (-1/2*alpha^2 - 4)/(-12*alpha^2 + 1/2*alpha - 1/95)
     1221        """
     1222        return self(self._field.random_element(*args, **kwds))
     1223
     1224    def degree(self):
     1225        """
     1226        Return the degree over the base field of this rational
     1227        function field. Since the base field is the rational function
     1228        field itself, the degree is 1.
     1229
     1230        EXAMPLES::
     1231       
     1232            sage: K.<t> = FunctionField(QQ)
     1233            sage: K.degree()
     1234            1
     1235        """
     1236        from sage.rings.integer_ring import ZZ
     1237        return ZZ(1)
     1238   
     1239    def gen(self, n=0):
     1240        """
     1241        Return the ``n``-th generator of this function field.  If ``n`` is not
     1242        0, then an IndexError is raised.
     1243
     1244        EXAMPLES::
     1245           
     1246            sage: K.<t> = FunctionField(QQ); K.gen()
     1247            t
     1248            sage: K.gen().parent()
     1249            Rational function field in t over Rational Field
     1250            sage: K.gen(1)
     1251            Traceback (most recent call last):
     1252            ...
     1253            IndexError: Only one generator.
     1254        """
     1255        if n != 0:
     1256            raise IndexError, "Only one generator."
     1257        return self._gen
     1258
     1259    def ngens(self):
     1260        """
     1261        Return the number of generators, which is 1.
     1262       
     1263        EXAMPLES::
     1264
     1265            sage: K.<t> = FunctionField(QQ)
     1266            sage: K.ngens()
     1267            1
     1268        """
     1269        return 1
     1270   
     1271    def base_field(self):
     1272        """
     1273        Return the base field of this rational function field, which is just
     1274        this function field itself.
     1275       
     1276        EXAMPLES::
     1277       
     1278            sage: K.<t> = FunctionField(GF(7))
     1279            sage: K.base_field()
     1280            Rational function field in t over Finite Field of size 7
     1281        """
     1282        return self
     1283
     1284    def hom(self, im_gens, base_morphism=None):
     1285        """
     1286        Create a homomorphism from self to another function field.
     1287
     1288        INPUT:
     1289
     1290            - ``im_gens`` -- exactly one element of some function field
     1291            - ``base_morphism`` -- ignored
     1292
     1293        OUTPUT:
     1294
     1295            - a map between function fields
     1296
     1297        EXAMPLES:
     1298
     1299        We make a map from a rational function field to itself::
     1300
     1301            sage: K.<x> = FunctionField(GF(7))
     1302            sage: K.hom( (x^4 + 2)/x)
     1303            Morphism of function fields defined by x |--> (x^4 + 2)/x       
     1304       
     1305        We construct a map from a rational function field into a
     1306        non-rational extension field::
     1307       
     1308            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     1309            sage: L.<y> = K.extension(y^3 + 6*x^3 + x)
     1310            sage: f = K.hom(y^2 + y  + 2); f
     1311            Morphism of function fields defined by x |--> y^2 + y + 2
     1312            sage: f(x)
     1313            y^2 + y + 2
     1314            sage: f(x^2)
     1315            5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4       
     1316        """
     1317        from sage.structure.category_object import CategoryObject
     1318        if isinstance(im_gens, CategoryObject):
     1319            return self.Hom(im_gens).natural_map()
     1320        if not isinstance(im_gens, (list,tuple)):
     1321            im_gens = [im_gens]
     1322        if len(im_gens) != 1:
     1323            raise ValueError, "there must be exactly one generator"
     1324        x = im_gens[0]
     1325        from maps import FunctionFieldMorphism_rational
     1326        return FunctionFieldMorphism_rational(self.Hom(x.parent()), x)
     1327
     1328    def field(self):
     1329        """
     1330        Return the underlying field, forgetting the function field
     1331        structure.
     1332       
     1333        EXAMPLES::
     1334
     1335            sage: K.<t> = FunctionField(GF(7))
     1336            sage: K.field()
     1337            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1338        """
     1339        return self._field
     1340
     1341    @cached_method
     1342    def maximal_order(self):
     1343        """
     1344        Return the maximal order of this function field.  Since this
     1345        is a rational function field it is of the form K(t), and the
     1346        maximal order is by definition K[t].
     1347       
     1348        EXAMPLES::
     1349       
     1350            sage: K.<t> = FunctionField(QQ)
     1351            sage: K.maximal_order()
     1352            Maximal order in Rational function field in t over Rational Field
     1353            sage: K.equation_order()
     1354            Maximal order in Rational function field in t over Rational Field
     1355        """
     1356        from function_field_order import FunctionFieldOrder_rational
     1357        return FunctionFieldOrder_rational(self)
     1358
     1359    equation_order = maximal_order
     1360
     1361    def constant_base_field(self):
     1362        """
     1363        Return the field that this rational function field is a
     1364        transcendental extension of.
     1365
     1366        EXAMPLES::
     1367
     1368            sage: K.<t> = FunctionField(QQ)
     1369            sage: K.constant_field()
     1370            Rational Field
     1371       
     1372        """
     1373        return self._constant_field
     1374
     1375    constant_field = constant_base_field
  • 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
    - +  
     1r"""
     2Function Field Elements
     3
     4AUTHORS:
     5
     6- William Stein: initial version
     7
     8- Robert Bradshaw (2010-05-27): cythonize function field elements
     9
     10- Julian Rueth (2011-06-28): treat zero correctly
     11
     12- Maarten Derickx (2011-09-11): added doctests, fixed pickling
     13"""
     14#*****************************************************************************
     15#       Copyright (C) 2010 William Stein <wstein@gmail.com>
     16#       Copyright (C) 2010 Robert Bradshaw <robertwb@math.washington.edu>
     17#       Copyright (C) 2011 Julian Rueth <julian.rueth@gmail.com>
     18#       Copyright (C) 2011 Maarten Derickx <m.derickx.student@gmail.com>
     19#
     20#  Distributed under the terms of the GNU General Public License (GPL)
     21#  as published by the Free Software Foundation; either version 2 of
     22#  the License, or (at your option) any later version.
     23#                  http://www.gnu.org/licenses/
     24#*****************************************************************************
     25
     26include "../../ext/stdsage.pxi"
     27
     28from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element
     29
     30def is_FunctionFieldElement(x):
     31    """
     32    Return True if x is any type of function field element.
     33   
     34    EXAMPLES::
     35
     36        sage: t = FunctionField(QQ,'t').gen()
     37        sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(t)
     38        True
     39        sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(0)
     40        False
     41    """
     42    if isinstance(x, FunctionFieldElement): return True
     43    from function_field import is_FunctionField
     44    return is_FunctionField(x.parent())
     45
     46def make_FunctionFieldElement(parent, element_class, representing_element):
     47    """
     48    Used for unpickling FunctionFieldElement objects (and subclasses).
     49   
     50    EXAMPLES::
     51   
     52        sage: from sage.rings.function_field.function_field_element import make_FunctionFieldElement
     53        sage: K.<x> = FunctionField(QQ)
     54        sage: make_FunctionFieldElement(K, K._element_class, (x+1)/x)
     55        (x + 1)/x
     56    """
     57    return element_class(parent, representing_element, reduce=False)
     58
     59cdef class FunctionFieldElement(FieldElement):
     60    """
     61    The abstract base class for function field elements.
     62   
     63    EXAMPLES::
     64
     65        sage: t = FunctionField(QQ,'t').gen()
     66        sage: isinstance(t, sage.rings.function_field.function_field_element.FunctionFieldElement)
     67        True
     68    """
     69
     70    cdef readonly object _x
     71    cdef readonly object _matrix
     72
     73    def __reduce__(self):
     74        """
     75        EXAMPLES::
     76       
     77            sage: K = FunctionField(QQ,'x')
     78            sage: f = K.random_element()
     79            sage: loads(f.dumps()) == f
     80            True
     81        """
     82        return (make_FunctionFieldElement,
     83                (self._parent, type(self), self._x))
     84
     85    cdef FunctionFieldElement _new_c(self):
     86        cdef FunctionFieldElement x = <FunctionFieldElement>PY_NEW_SAME_TYPE(self)
     87        x._parent = self._parent
     88        return x
     89   
     90    def _latex_(self):
     91        """
     92        EXAMPLES::
     93       
     94            sage: K.<t> = FunctionField(QQ)
     95            sage: latex((t+1)/t)
     96            \frac{t + 1}{t}
     97            sage: latex((t+1)/t^67)
     98            \frac{t + 1}{t^{67}}
     99            sage: latex((t+1/2)/t^67)
     100            \frac{t + \frac{1}{2}}{t^{67}}
     101        """
     102        return self._x._latex_()
     103   
     104    def matrix(self):
     105        r"""
     106        Return the matrix of multiplication by self, interpreting self as an element
     107        of a vector space over its base field.
     108
     109        EXAMPLES:
     110
     111        A rational function field::
     112       
     113            sage: K.<t> = FunctionField(QQ)
     114            sage: t.matrix()
     115            [t]
     116            sage: (1/(t+1)).matrix()
     117            [1/(t + 1)]
     118
     119        Now an example in a nontrivial extension of a rational function field::
     120       
     121            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     122            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     123            sage: y.matrix()
     124            [     0      1]
     125            [-4*x^3      x]
     126            sage: y.matrix().charpoly('Z')
     127            Z^2 - x*Z + 4*x^3
     128
     129        An example in a relative extension, where neither function
     130        field is rational::
     131
     132            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     133            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     134            sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - y^2*T + x)
     135            sage: alpha.matrix()
     136            [          0           1           0]
     137            [          0           0           1]
     138            [         -x x*y - 4*x^3           0]
     139
     140        We show that this matrix does indeed work as expected when making a
     141        vector space from a function field::
     142
     143            sage: K.<x>=FunctionField(QQ)
     144            sage: R.<y> = K[]
     145            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     146            sage: V, from_V, to_V = L.vector_space()
     147            sage: y5 = to_V(y^5); y5
     148            ((x^4 + 1)/x, 2*x, 0, 0, 0)
     149            sage: y4y = to_V(y^4) * y.matrix(); y4y
     150            ((x^4 + 1)/x, 2*x, 0, 0, 0)
     151            sage: y5 == y4y
     152            True
     153        """
     154        if self._matrix is None:
     155            # Multiply each power of field generator on the left by this
     156            # element; make matrix whose rows are the coefficients of the
     157            # result, and transpose.
     158            K = self.parent()
     159            v = []
     160            x = K.gen()
     161            a = K(1)
     162            d = K.degree()
     163            for n in range(d):
     164                v += (a*self).list()
     165                a *= x
     166            k = K.base_ring()
     167            import sage.matrix.matrix_space
     168            M = sage.matrix.matrix_space.MatrixSpace(k, d)
     169            self._matrix = M(v)
     170        return self._matrix
     171
     172    def trace(self):
     173        """
     174        Return the trace of this function field element.
     175
     176        EXAMPLES::
     177
     178            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     179            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     180            sage: y.trace()
     181            x
     182        """
     183        return self.matrix().trace()
     184
     185    def norm(self):
     186        """
     187        Return the norm of this function field element.
     188
     189        EXAMPLES::
     190       
     191            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     192            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     193            sage: y.norm()
     194            4*x^3
     195
     196        The norm is relative::
     197       
     198            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     199            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[]
     200            sage: M.<z> = L.extension(z^3 - y^2*z + x)
     201            sage: z.norm()
     202            -x
     203            sage: z.norm().parent()
     204            Function field in y defined by y^2 - x*y + 4*x^3
     205        """
     206        return self.matrix().determinant()
     207
     208    def characteristic_polynomial(self, *args, **kwds):
     209        """
     210        Return the characteristic polynomial of this function field
     211        element.  Give an optional input string to name the variable
     212        in the characteristic polynomial.
     213
     214        EXAMPLES::
     215
     216            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     217            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[]
     218            sage: M.<z> = L.extension(z^3 - y^2*z + x)
     219            sage: x.characteristic_polynomial('W')
     220            W - x
     221            sage: y.characteristic_polynomial('W')
     222            W^2 - x*W + 4*x^3
     223            sage: z.characteristic_polynomial('W')
     224            W^3 + (-x*y + 4*x^3)*W + x
     225        """
     226        return self.matrix().characteristic_polynomial(*args, **kwds)
     227
     228    charpoly = characteristic_polynomial
     229
     230    def minimal_polynomial(self, *args, **kwds):
     231        """
     232        Return the minimal polynomial of this function field element.
     233        Give an optional input string to name the variable in the
     234        characteristic polynomial.
     235
     236        EXAMPLES::
     237
     238            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     239            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[]
     240            sage: M.<z> = L.extension(z^3 - y^2*z + x)
     241            sage: x.minimal_polynomial('W')
     242            W - x
     243            sage: y.minimal_polynomial('W')
     244            W^2 - x*W + 4*x^3
     245            sage: z.minimal_polynomial('W')
     246            W^3 + (-x*y + 4*x^3)*W + x
     247        """
     248        return self.matrix().minimal_polynomial(*args, **kwds)
     249
     250    minpoly = minimal_polynomial
     251   
     252    def is_integral(self):
     253        r"""
     254        Determine if self is integral over the maximal order of the base field.
     255       
     256        EXAMPLES::
     257       
     258            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     259            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     260            sage: y.is_integral()
     261            True
     262            sage: (y/x).is_integral()
     263            True
     264            sage: (y/x)^2 - (y/x) + 4*x
     265            0
     266            sage: (y/x^2).is_integral()
     267            False
     268            sage: (y/x).minimal_polynomial('W')
     269            W^2 - W + 4*x           
     270        """
     271        R = self.parent().base_field().maximal_order()
     272        return all([a in R for a in self.minimal_polynomial()])
     273
     274cdef class FunctionFieldElement_polymod(FunctionFieldElement):
     275    """
     276    Elements of a finite extension of a function field.
     277
     278    EXAMPLES::
     279
     280        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     281        sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     282        sage: x*y + 1/x^3
     283        x*y + 1/x^3       
     284    """
     285    def __init__(self, parent, x, reduce=True):
     286        """
     287        EXAMPLES::
     288
     289            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     290            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     291            sage: type(y)
     292            <type 'sage.rings.function_field.function_field_element.FunctionFieldElement_polymod'>             
     293        """
     294        FieldElement.__init__(self, parent)
     295        if reduce:
     296            self._x = x % self._parent.polynomial()
     297        else:
     298            self._x = x
     299   
     300    def element(self):
     301        """
     302        Return the underlying polynomial that represents this element.
     303       
     304        EXAMPLES::
     305            sage: K.<x> = FunctionField(QQ); R.<T> = K[]
     306            sage: L.<y> = K.extension(T^2 - x*T + 4*x^3)
     307            sage: f = y/x^2 + x/(x^2+1); f
     308            1/x^2*y + x/(x^2 + 1)
     309            sage: f.element()
     310            1/x^2*T + x/(x^2 + 1)
     311            sage: type(f.element())
     312            <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>       
     313        """
     314        return self._x
     315
     316    def _repr_(self):
     317        """
     318        EXAMPLES::
     319
     320            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     321            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     322            sage: y._repr_()
     323            'y'
     324        """
     325        return self._x._repr(name=self.parent().variable_name())
     326       
     327    def __nonzero__(self):
     328        """
     329        EXAMPLES::
     330
     331            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     332            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     333            sage: bool(y)
     334            True
     335            sage: bool(L(0))
     336            False
     337            sage: bool(L.coerce(L.polynomial()))
     338            False
     339        """
     340        return not not self._x
     341
     342    cdef int _cmp_c_impl(self, Element other) except -2:
     343        """
     344        EXAMPLES::
     345
     346            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     347            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     348            sage: cmp(L(0), 0)
     349            0
     350            sage: cmp(y, L(2)) != 0
     351            True
     352        """
     353        cdef FunctionFieldElement left = <FunctionFieldElement>self
     354        cdef FunctionFieldElement right = <FunctionFieldElement>other
     355        return cmp(left._x, right._x)
     356
     357    cpdef ModuleElement _add_(self, ModuleElement right):
     358        """
     359        EXAMPLES::
     360
     361            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     362            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     363            sage: (2*y + x/(1+x^3))  +  (3*y + 5*x*y)         # indirect doctest
     364            (5*x + 5)*y + x/(x^3 + 1)
     365            sage: (y^2 - x*y + 4*x^3)==0                      # indirect doctest
     366            True
     367            sage: -y+y
     368            0
     369        """
     370        cdef FunctionFieldElement res = self._new_c()
     371        res._x = self._x + (<FunctionFieldElement>right)._x
     372        return res
     373
     374    cpdef ModuleElement _sub_(self, ModuleElement right):
     375        """
     376        EXAMPLES::
     377
     378            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     379            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     380            sage: (2*y + x/(1+x^3))  -  (3*y + 5*x*y)         # indirect doctest
     381            (-5*x - 1)*y + x/(x^3 + 1)
     382            sage: y-y
     383            0
     384        """
     385        cdef FunctionFieldElement res = self._new_c()
     386        res._x = self._x - (<FunctionFieldElement>right)._x
     387        return res
     388
     389    cpdef RingElement _mul_(self, RingElement right):
     390        """
     391        EXAMPLES::
     392
     393            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     394            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     395            sage: y  *  (3*y + 5*x*y)                          # indirect doctest
     396            (5*x^2 + 3*x)*y - 20*x^4 - 12*x^3
     397        """
     398        cdef FunctionFieldElement res = self._new_c()
     399        res._x = (self._x * (<FunctionFieldElement>right)._x) % self._parent.polynomial()
     400        return res
     401
     402    cpdef RingElement _div_(self, RingElement right):
     403        """
     404        EXAMPLES::
     405
     406            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     407            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     408            sage: (2*y + x/(1+x^3))  /  (2*y + x/(1+x^3))       # indirect doctest
     409            1
     410            sage: 1 / (y^2 - x*y + 4*x^3)                       # indirect doctest
     411            Traceback (most recent call last):
     412            ...
     413            ZeroDivisionError: Cannot invert 0
     414        """
     415        return self * ~right
     416
     417    def __invert__(self):
     418        """
     419        EXAMPLES::
     420
     421            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     422            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     423            sage: a = ~(2*y + 1/x); a                           # indirect doctest
     424            (-x^2/(8*x^5 + x^2 + 1/2))*y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
     425            sage: a*(2*y + 1/x)
     426            1
     427        """
     428        if self.is_zero():
     429            raise ZeroDivisionError, "Cannot invert 0"
     430        P = self._parent
     431        return P(self._x.xgcd(P._polynomial)[1])
     432
     433    def list(self):
     434        """
     435        Return a list of coefficients of self, i.e., if self is an element of
     436        a function field K[y]/(f(y)), then return the coefficients of the
     437        reduced presentation as a polynomial in K[y].
     438
     439        EXAMPLES::
     440
     441            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     442            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     443            sage: a = ~(2*y + 1/x); a
     444            (-x^2/(8*x^5 + x^2 + 1/2))*y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
     445            sage: a.list()
     446            [(2*x^3 + x)/(16*x^5 + 2*x^2 + 1), -x^2/(8*x^5 + x^2 + 1/2)]
     447            sage: (x*y).list()
     448            [0, x]
     449        """
     450        return self._x.padded_list(self.parent().degree())
     451       
     452cdef class FunctionFieldElement_rational(FunctionFieldElement):
     453    """
     454    Elements of a rational function field.
     455
     456    EXAMPLES::
     457   
     458        sage: K.<t> = FunctionField(QQ); K
     459        Rational function field in t over Rational Field
     460    """
     461    def __init__(self, parent, x, reduce=True):
     462        """
     463        EXAMPLES::
     464       
     465            sage: FunctionField(QQ,'t').gen()^3
     466            t^3
     467        """
     468        FieldElement.__init__(self, parent)
     469        self._x = x
     470 
     471    def element(self):
     472        """
     473        Return the underlying fraction field element that represents this element.
     474
     475        EXAMPLES::
     476
     477            sage: K.<t> = FunctionField(GF(7))
     478            sage: t.element()
     479            t
     480            sage: type(t.element())
     481            <type 'sage.rings.fraction_field_FpT.FpTElement'>       
     482
     483            sage: K.<t> = FunctionField(GF(131101))
     484            sage: t.element()
     485            t
     486            sage: type(t.element())
     487            <class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
     488        """
     489        return self._x
     490
     491    def list(self):
     492        """
     493        Return a list of coefficients of self, i.e., if self is an element of
     494        a function field K[y]/(f(y)), then return the coefficients of the
     495        reduced presentation as a polynomial in K[y].
     496        Since self is a member of a rational function field, this simply returns
     497        the list `[self]`
     498
     499        EXAMPLES::
     500
     501            sage: K.<t> = FunctionField(QQ)
     502            sage: t.list()
     503            [t]
     504        """
     505        return [self]
     506
     507    def _repr_(self):
     508        """
     509        EXAMPLES::
     510
     511            sage: K.<t> = FunctionField(QQ)
     512            sage: t._repr_()
     513            't'
     514        """
     515        return repr(self._x)
     516       
     517    def __nonzero__(self):
     518        """
     519        EXAMPLES::
     520
     521            sage: K.<t> = FunctionField(QQ)
     522            sage: bool(t)
     523            True
     524            sage: bool(K(0))
     525            False
     526            sage: bool(K(1))
     527            True
     528        """
     529        return not not self._x
     530
     531    cdef int _cmp_c_impl(self, Element other) except -2:
     532        """
     533        EXAMPLES::
     534
     535            sage: K.<t> = FunctionField(QQ)
     536            sage: cmp(t, 0)
     537            1
     538            sage: cmp(t, t^2)
     539            -1
     540        """
     541        cdef int c = cmp(type(self), type(other))
     542        if c: return c
     543        cdef FunctionFieldElement left = <FunctionFieldElement>self
     544        cdef FunctionFieldElement right = <FunctionFieldElement>other
     545        c = cmp(left._parent, right._parent)
     546        return c or cmp(left._x, right._x)
     547
     548    cpdef ModuleElement _add_(self, ModuleElement right):
     549        """
     550        EXAMPLES::
     551       
     552            sage: K.<t> = FunctionField(QQ)
     553            sage: t + (3*t^3)                      # indirect doctest
     554            3*t^3 + t
     555        """
     556        cdef FunctionFieldElement res = self._new_c()
     557        res._x = self._x + (<FunctionFieldElement>right)._x
     558        return res
     559
     560    cpdef ModuleElement _sub_(self, ModuleElement right):
     561        """
     562        EXAMPLES::
     563
     564            sage: K.<t> = FunctionField(QQ)
     565            sage: t - (3*t^3)                      # indirect doctest
     566            -3*t^3 + t
     567        """
     568        cdef FunctionFieldElement res = self._new_c()
     569        res._x = self._x - (<FunctionFieldElement>right)._x
     570        return res
     571
     572    cpdef RingElement _mul_(self, RingElement right):
     573        """
     574        EXAMPLES::
     575
     576            sage: K.<t> = FunctionField(QQ)
     577            sage: (t+1) * (t^2-1)                  # indirect doctest
     578            t^3 + t^2 - t - 1
     579        """
     580        cdef FunctionFieldElement res = self._new_c()
     581        res._x = self._x * (<FunctionFieldElement>right)._x
     582        return res
     583
     584    cpdef RingElement _div_(self, RingElement right):
     585        """
     586        EXAMPLES::
     587
     588            sage: K.<t> = FunctionField(QQ)
     589            sage: (t+1) / (t^2 - 1)                # indirect doctest
     590            1/(t - 1)
     591        """
     592        cdef FunctionFieldElement res = self._new_c()
     593        res._parent = self._parent.fraction_field()
     594        res._x = self._x / (<FunctionFieldElement>right)._x
     595        return res
     596
     597    def numerator(self):
     598        """
     599        EXAMPLES::
     600
     601            sage: K.<t> = FunctionField(QQ)
     602            sage: f = (t+1) / (t^2 - 1/3); f
     603            (t + 1)/(t^2 - 1/3)
     604            sage: f.numerator()
     605            t + 1
     606        """
     607        return self._x.numerator()
     608
     609    def denominator(self):
     610        """
     611        EXAMPLES::
     612
     613            sage: K.<t> = FunctionField(QQ)
     614            sage: f = (t+1) / (t^2 - 1/3); f
     615            (t + 1)/(t^2 - 1/3)
     616            sage: f.denominator()
     617            t^2 - 1/3
     618        """
     619        return self._x.denominator()
     620   
     621    def valuation(self, v):
     622        """
     623        EXAMPLES::
     624       
     625            sage: K.<t> = FunctionField(QQ)
     626            sage: f = (t-1)^2 * (t+1) / (t^2 - 1/3)^3
     627            sage: f.valuation(t-1)
     628            2
     629            sage: f.valuation(t)
     630            0
     631            sage: f.valuation(t^2 - 1/3)
     632            -3
     633        """
     634        R = self._parent._ring
     635        return self._x.valuation(R(self._parent(v)._x))
     636   
     637    def is_square(self):
     638        """
     639        Returns whether self is a square.
     640       
     641        EXAMPLES::
     642           
     643            sage: K.<t> = FunctionField(QQ)
     644            sage: t.is_square()
     645            False
     646            sage: (t^2/4).is_square()
     647            True
     648            sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square()
     649            True
     650           
     651            sage: K.<t> = FunctionField(GF(5))
     652            sage: (-t^2).is_square()
     653            True
     654            sage: (-t^2).sqrt()
     655            2*t
     656        """
     657        return self._x.is_square()
     658   
     659    def sqrt(self, all=False):
     660        """
     661        Returns the square root of self.
     662       
     663        EXAMPLES::
     664       
     665            sage: K.<t> = FunctionField(QQ)
     666            sage: f = t^2 - 2 + 1/t^2; f.sqrt()
     667            (t^2 - 1)/t
     668            sage: f = t^2; f.sqrt(all=True)
     669            [t, -t]
     670           
     671        TESTS::
     672       
     673            sage: K(4/9).sqrt()
     674            2/3
     675            sage: K(0).sqrt(all=True)
     676            [0]
     677        """
     678        if all:
     679            return [self._parent(r) for r in self._x.sqrt(all=True)]
     680        else:
     681            return self._parent(self._x.sqrt())
     682
     683    def factor(self):
     684        """
     685        Factor this rational function.
     686       
     687        EXAMPLES::
     688
     689            sage: K.<t> = FunctionField(QQ)
     690            sage: f = (t+1) / (t^2 - 1/3)
     691            sage: f.factor()
     692            (t + 1) * (t^2 - 1/3)^-1
     693            sage: (7*f).factor()
     694            (7) * (t + 1) * (t^2 - 1/3)^-1
     695            sage: ((7*f).factor()).unit()
     696            7
     697            sage: (f^3).factor()
     698            (t + 1)^3 * (t^2 - 1/3)^-3
     699        """
     700        P = self.parent()
     701        F = self._x.factor()
     702        from sage.structure.factorization import Factorization
     703        return Factorization([(P(a),e) for a,e in F], unit=F.unit())
     704
     705    def inverse_mod(self, I):
     706        r"""
     707        Return an inverse of self modulo the integral ideal `I`, if
     708        defined, i.e., if `I` and self together generate the unit
     709        ideal.
     710
     711        EXAMPLES::
     712
     713            sage: K.<x> = FunctionField(QQ)
     714            sage: O = K.maximal_order(); I = O.ideal(x^2+1)
     715            sage: t = O(x+1).inverse_mod(I); t
     716            -1/2*x + 1/2
     717            sage: (t*(x+1) - 1) in I
     718            True           
     719        """
     720        assert  len(I.gens()) == 1
     721        f = I.gens()[0]._x
     722        assert f.denominator() == 1
     723        assert self._x.denominator() == 1
     724        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
    - +  
     1r"""
     2Ideals in Function Fields
     3
     4AUTHORS:
     5
     6- William Stein (2010): initial version
     7
     8- Maarten Derickx (2011-09-14): fixed ideal_with_gens_over_base()
     9
     10EXAMPLES:
     11
     12Ideals in the maximal order of a rational function field::
     13
     14    sage: K.<x> = FunctionField(QQ)
     15    sage: O = K.maximal_order()
     16    sage: I = O.ideal(x^3+1); I
     17    Ideal (x^3 + 1) of Maximal order in Rational function field in x over Rational Field
     18    sage: I^2
     19    Ideal (x^6 + 2*x^3 + 1) of Maximal order in Rational function field in x over Rational Field
     20    sage: ~I
     21    Ideal (1/(x^3 + 1)) of Maximal order in Rational function field in x over Rational Field
     22    sage: ~I * I
     23    Ideal (1) of Maximal order in Rational function field in x over Rational Field
     24
     25Ideals in the equation order of an extension of a rational function field::
     26
     27    sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     28    sage: L.<y> = K.extension(y^2-x^3-1)
     29    sage: O = L.equation_order()
     30    sage: I = O.ideal(y); I
     31    Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1
     32    sage: I^2
     33    Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1
     34    sage: ~I
     35    Ideal (-1, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 - x^3 - 1
     36    sage: ~I * I
     37    Ideal (1, y) of Order in Function field in y defined by y^2 - x^3 - 1
     38    sage: I.intersection(~I)
     39    Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1
     40"""
     41#*****************************************************************************
     42#       Copyright (C) 2010 William Stein <wstein@gmail.com>
     43#       Copyright (C) 2011 Maarten Derickx <m.derickx.student@gmail.com>
     44#
     45#  Distributed under the terms of the GNU General Public License (GPL)
     46#  as published by the Free Software Foundation; either version 2 of
     47#  the License, or (at your option) any later version.
     48#                  http://www.gnu.org/licenses/
     49#*****************************************************************************
     50
     51from sage.rings.ideal import Ideal_generic
     52
     53class FunctionFieldIdeal(Ideal_generic):
     54    """
     55    A fractional ideal of a function field.
     56
     57    EXAMPLES::
     58
     59        sage: K.<x> = FunctionField(GF(7))
     60        sage: O = K.maximal_order()
     61        sage: I = O.ideal(x^3+1)
     62        sage: isinstance(I, sage.rings.function_field.function_field_ideal.FunctionFieldIdeal)
     63        True   
     64    """
     65    pass
     66
     67class FunctionFieldIdeal_module(FunctionFieldIdeal):
     68    """
     69    A fractional ideal specified by a finitely generated module over
     70    the integers of the base field.
     71
     72    EXAMPLES:
     73
     74    An ideal in an extension of a rational function field::
     75
     76        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     77        sage: L.<y> = K.extension(y^2 - x^3 - 1)
     78        sage: O = L.equation_order()
     79        sage: I = O.ideal(y)
     80        sage: I
     81        Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1
     82        sage: I^2
     83        Ideal (x^3 + 1, (-x^3 - 1)*y) of Order in Function field in y defined by y^2 - x^3 - 1   
     84    """
     85    def __init__(self, ring, module):
     86        """
     87        INPUT:
     88
     89            - ``ring`` -- an order in a function field
     90            - ``module`` -- a module
     91
     92        EXAMPLES::
     93
     94            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     95            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     96            sage: O = L.equation_order()
     97            sage: I = O.ideal(y)
     98            sage: type(I)
     99            <class 'sage.rings.function_field.function_field_ideal.FunctionFieldIdeal_module'>
     100        """
     101        self._ring = ring
     102        self._module = module
     103        self._structure = ring.fraction_field().vector_space()
     104        V, from_V, to_V = self._structure
     105        gens = tuple([from_V(a) for a in module.basis()])
     106        Ideal_generic.__init__(self, ring, gens, coerce=False)
     107
     108    def __contains__(self, x):
     109        """
     110        Return True if x is in this ideal.
     111
     112        EXAMPLES::
     113
     114            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     115            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     116            sage: O = L.equation_order()
     117            sage: I = O.ideal_with_gens_over_base([1, y]);  I
     118            Ideal (1, y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     119            sage: y in I
     120            True
     121            sage: y/x in I
     122            False
     123            sage: y^2 - 2 in I
     124            True
     125        """
     126        return self._structure[2](x) in self._module
     127
     128    def module(self):
     129        """
     130        Return module over the maximal order of the base field that
     131        underlies self.
     132
     133        The formation of this module is compatible with the vector
     134        space corresponding to the function field.
     135
     136        OUTPUT:
     137
     138            - a module over the maximal order of the base field of self
     139
     140        EXAMPLES::
     141
     142            sage: K.<x> = FunctionField(GF(7))
     143            sage: O = K.maximal_order(); O
     144            Maximal order in Rational function field in x over Finite Field of size 7
     145            sage: K.polynomial_ring()
     146            Univariate Polynomial Ring in x over Rational function field in x over Finite Field of size 7
     147            sage: I = O.ideal_with_gens_over_base([x^2 + 1, x*(x^2+1)])
     148            sage: I.gens()
     149            (x^2 + 1,)
     150            sage: I.module()
     151            Free module of degree 1 and rank 1 over Maximal order in Rational function field in x over Finite Field of size 7
     152            User basis matrix:
     153            [x^2 + 1]
     154            sage: V, from_V, to_V = K.vector_space(); V
     155            Vector space of dimension 1 over Rational function field in x over Finite Field of size 7
     156            sage: I.module().is_submodule(V)
     157            True       
     158        """
     159        return self._module
     160
     161    def __add__(self, other):
     162        """
     163        Add self and ``other``.
     164       
     165        EXAMPLES::
     166       
     167            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     168            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     169            sage: O = L.equation_order()
     170            sage: I = O.ideal(y); J = O.ideal(y+1)
     171            sage: Z = I + J; Z
     172            Ideal (y + 1, 6*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     173            sage: 1 in Z
     174            True
     175            sage: O.ideal(y^2) + O.ideal(y^3) == O.ideal(y^2,y^3)
     176            True
     177        """
     178        if not isinstance(other, FunctionFieldIdeal_module):
     179            other = self.ring().ideal(other)
     180        return FunctionFieldIdeal_module(self.ring(), self.module() + other.module())
     181
     182    def intersection(self, other):
     183        """
     184        Return the intersection of the ideals self and ``other``.
     185       
     186        EXAMPLES::
     187
     188            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     189            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     190            sage: O = L.equation_order()
     191            sage: I = O.ideal(y^3); J = O.ideal(y^2)
     192            sage: Z = I.intersection(J); Z
     193            Ideal (x^6 + 2*x^3 + 1, (6*x^3 + 6)*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     194            sage: y^2 in Z
     195            False
     196            sage: y^3 in Z
     197            True
     198        """
     199        if not isinstance(other, FunctionFieldIdeal_module):
     200            other = self.ring().ideal(other)
     201        if self.ring() != other.ring():
     202            raise ValueError, "rings must be the same"
     203        return FunctionFieldIdeal_module(self.ring(), self.module().intersection(other.module()))
     204
     205    def __cmp__(self, other):
     206        """
     207        Compare self and ``other``.
     208       
     209        EXAMPLES::
     210
     211            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     212            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     213            sage: O = L.equation_order()
     214            sage: I = O.ideal(y*(y+1)); J = O.ideal((y^2-2)*(y+1))
     215            sage: I+J == J+I            # indirect test
     216            True
     217            sage: I == J
     218            False
     219            sage: I < J
     220            True
     221            sage: J < I
     222            False       
     223        """
     224        if not isinstance(other, FunctionFieldIdeal_module):
     225            other = self.ring().ideal(other)
     226        if self.ring() != other.ring():
     227            raise ValueError, "rings must be the same"
     228        return cmp(self.module(), other.module())
     229
     230    def __invert__(self):
     231        """
     232        Return the inverse of this fractional ideal.
     233
     234        EXAMPLES::
     235
     236            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     237            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     238            sage: O = L.equation_order()
     239            sage: I = O.ideal(y)
     240            sage: ~I
     241            Ideal (6, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     242            sage: I^(-1)
     243            Ideal (6, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     244            sage: ~I * I
     245            Ideal (1, y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     246        """
     247        if len(self.gens()) == 0:
     248            raise ZeroDivisionError
     249
     250        # NOTE: If  I = (g0, ..., gn), then {x : x*I is in R}
     251        # is the intersection over i of {x : x*gi is in R}
     252        # Thus (I + J)^(-1) = I^(-1) intersect J^(-1).
     253       
     254        G = self.gens()
     255        R = self.ring()
     256        inv = R.ideal(~G[0])
     257        for g in G[1:]:
     258            inv = inv.intersection(R.ideal(~g))
     259        return inv
     260
     261def ideal_with_gens(R, gens):
     262    """
     263    Return fractional ideal in the order ``R`` with generators ``gens``
     264    over ``R``.
     265
     266    EXAMPLES::
     267
     268        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     269        sage: L.<y> = K.extension(y^2 - x^3 - 1)
     270        sage: O = L.equation_order()
     271        sage: sage.rings.function_field.function_field_ideal.ideal_with_gens(O, [y])
     272        Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1
     273    """
     274    K = R.fraction_field()
     275    return ideal_with_gens_over_base(R, [b*K(g) for b in R.basis() for g in gens])
     276
     277def ideal_with_gens_over_base(R, gens):
     278    """
     279    Return fractional ideal in the order ``R`` with generators ``gens``
     280    over the maximal order of the base field.
     281
     282    EXAMPLES::
     283
     284        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     285        sage: L.<y> = K.extension(y^2 - x^3 - 1)
     286        sage: O = L.equation_order()
     287        sage: sage.rings.function_field.function_field_ideal.ideal_with_gens_over_base(O, [x^3+1,-y])
     288        Ideal (x^3 + 1, -y) of Order in Function field in y defined by y^2 - x^3 - 1   
     289   
     290    TESTS::
     291
     292        sage: K.<x> = FunctionField(QQ)
     293        sage: O = K.maximal_order()
     294        sage: I = O*x
     295        sage: ~I
     296        Ideal (1/x) of Maximal order in Rational function field in x over Rational Field
     297        sage: ~I == O.ideal(1/x)
     298        True
     299        sage: O.ideal([x,1/x])
     300        Ideal (1/x) of Maximal order in Rational function field in x over Rational Field
     301        sage: O.ideal([1/x,1/(x+1)])
     302        Ideal (1/(x^2 + x)) of Maximal order in Rational function field in x over Rational Field
     303    """
     304    K = R.fraction_field()
     305    V, from_V, to_V = K.vector_space()
     306
     307    # We handle the case of a rational function field separately,
     308    # since this is the base case and is used, e.g,. internally
     309    # by the linear algebra Hermite form code.
     310    import function_field_order
     311    if isinstance(R, function_field_order.FunctionFieldOrder_rational):
     312        from sage.modules import free_module_element
     313        gens = free_module_element.vector(x.element() for x in gens)
     314        d = gens.denominator()
     315        gens *= d
     316        v = R._ring.ideal(gens.list()).gens_reduced()
     317        assert len(v) == 1
     318        basis = [to_V(v[0]/d)]
     319        M = V.span_of_basis(basis, check=False, already_echelonized=True, base_ring=R)
     320    else:
     321        # General case
     322        S = V.base_field().maximal_order()
     323        M = V.span([to_V(b) for b in gens], base_ring=S)
     324
     325    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
    - +  
     1r"""
     2Orders in Function Fields
     3
     4AUTHORS:
     5
     6- William Stein (2010): initial version
     7
     8- Maarten Derickx (2011-09-14): fixed ideal_with_gens_over_base() for rational function fields
     9
     10- Julian Rueth (2011-09-14): added check in _element_constructor_
     11
     12EXAMPLES:
     13
     14Maximal orders in rational function fields::
     15
     16    sage: K.<x> = FunctionField(QQ)
     17    sage: O = K.maximal_order()
     18    sage: I = O.ideal(1/x); I
     19    Ideal (1/x) of Maximal order in Rational function field in x over Rational Field
     20    sage: 1/x in O
     21    False
     22
     23Equation orders in extensions of rational function fields::
     24
     25    sage: K.<x> = FunctionField(GF(3)); R.<y> = K[]
     26    sage: L.<y> = K.extension(y^3-y-x)
     27    sage: O = L.equation_order()
     28    sage: 1/y in O
     29    False
     30    sage: x/y in O
     31    True
     32"""
     33#*****************************************************************************
     34#       Copyright (C) 2010 William Stein <wstein@gmail.com>
     35#       Copyright (C) 2011 Maarten Derickx <m.derickx.student@gmail.com>
     36#       Copyright (C) 2011 Julian Rueth <julian.rueth@gmail.com>
     37#
     38#  Distributed under the terms of the GNU General Public License (GPL)
     39#  as published by the Free Software Foundation; either version 2 of
     40#  the License, or (at your option) any later version.
     41#                  http://www.gnu.org/licenses/
     42#*****************************************************************************
     43
     44from sage.rings.ring import IntegralDomain, PrincipalIdealDomain
     45from sage.rings.ideal import is_Ideal
     46
     47class FunctionFieldOrder(IntegralDomain):
     48    """
     49    Base class for orders in function fields.
     50    """
     51    def __init__(self, fraction_field):
     52        """
     53        INPUT:
     54
     55            - ``fraction_field`` -- the function field in which this is an order.
     56
     57        EXAMPLES::
     58
     59            sage: R = FunctionField(QQ,'y').maximal_order()
     60            sage: isinstance(R, sage.rings.function_field.function_field_order.FunctionFieldOrder)
     61            True
     62        """
     63        IntegralDomain.__init__(self, self)
     64        self._fraction_field = fraction_field
     65
     66    def _repr_(self):
     67        """
     68        EXAMPLES::
     69
     70            sage: FunctionField(QQ,'y').maximal_order()._repr_()
     71            'Maximal order in Rational function field in y over Rational Field'
     72        """
     73        return "Order in %s"%self.fraction_field()
     74
     75    def is_finite(self):
     76        """
     77        Returns False since orders are never finite.
     78
     79        EXAMPLES::
     80
     81            sage: FunctionField(QQ,'y').maximal_order().is_finite()
     82            False
     83        """
     84        return False
     85
     86    def is_field(self, proof=True):
     87        """
     88        Returns False since orders are never fields.
     89
     90        EXAMPLES::
     91
     92            sage: FunctionField(QQ,'y').maximal_order().is_field()
     93            False
     94        """
     95        return False
     96
     97    def is_noetherian(self):
     98        """
     99        Returns True since orders in function fields are noetherian.
     100       
     101        EXAMPLES::
     102
     103            sage: FunctionField(QQ,'y').maximal_order().is_noetherian()
     104            True
     105        """
     106        return True
     107
     108    def fraction_field(self):
     109        """
     110        Returns the function field in which this is an order.
     111
     112        EXAMPLES::
     113
     114            sage: FunctionField(QQ,'y').maximal_order().fraction_field()
     115            Rational function field in y over Rational Field
     116        """
     117        return self._fraction_field
     118
     119    function_field = fraction_field
     120   
     121    def ideal_with_gens_over_base(self, gens):
     122        """
     123        Returns the fractional ideal with basis ``gens`` over the
     124        maximal order of the base field. That this is really an ideal
     125        is not checked.
     126
     127        INPUT:
     128
     129            - ``gens`` -- list of elements that are a basis for the
     130              ideal over the maximal order of the base field
     131           
     132        EXAMPLES:
     133
     134        We construct an ideal in a rational function field::
     135       
     136            sage: K.<y> = FunctionField(QQ)
     137            sage: O = K.maximal_order()
     138            sage: I = O.ideal_with_gens_over_base([y]); I
     139            Ideal (y) of Maximal order in Rational function field in y over Rational Field
     140            sage: I*I
     141            Ideal (y^2) of Maximal order in Rational function field in y over Rational Field
     142
     143        We construct some ideals in a nontrivial function field::
     144
     145            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     146            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     147            sage: O = L.equation_order(); O
     148            Order in Function field in y defined by y^2 + 6*x^3 + 6
     149            sage: I = O.ideal_with_gens_over_base([1, y]);  I
     150            Ideal (1, y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     151            sage: I.module()
     152            Free module of degree 2 and rank 2 over Maximal order in Rational function field in x over Finite Field of size 7
     153            Echelon basis matrix:
     154            [1 0]
     155            [0 1]
     156
     157        There is no check if the resulting object is really an ideal::
     158
     159            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     160            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     161            sage: O = L.equation_order()
     162            sage: I = O.ideal_with_gens_over_base([y]); I
     163            Ideal (y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     164            sage: y in I
     165            True
     166            sage: y^2 in I
     167            False
     168        """
     169        from function_field_ideal import ideal_with_gens_over_base
     170        return ideal_with_gens_over_base(self, [self(a) for a in gens])
     171
     172    def ideal(self, *gens):
     173        """
     174        Returns the fractional ideal generated by the elements in ``gens``.
     175
     176        INPUT:
     177
     178            - ``gens`` -- a list of generators or an ideal in a ring which
     179                          coerces to this order.
     180
     181        EXAMPLES::
     182
     183            sage: K.<y> = FunctionField(QQ)
     184            sage: O = K.maximal_order()
     185            sage: O.ideal(y)
     186            Ideal (y) of Maximal order in Rational function field in y over Rational Field
     187            sage: O.ideal([y,1/y]) == O.ideal(y,1/y) # multiple generators may be given as a list
     188            True
     189
     190        A fractional ideal of a nontrivial extension::
     191
     192            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     193            sage: O = K.maximal_order()
     194            sage: I = O.ideal(x^2-4)
     195            sage: L.<y> = K.extension(y^2 - x^3 - 1)
     196            sage: S = L.equation_order()
     197            sage: S.ideal(1/y)
     198            Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6       
     199            sage: I2 = S.ideal(x^2-4); I2
     200            Ideal (x^2 + 3, (x^2 + 3)*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     201            sage: I2 == S.ideal(I)
     202            True
     203        """
     204        if len(gens) == 1:
     205            gens = gens[0]
     206            if not isinstance(gens, (list, tuple)):
     207                if is_Ideal(gens):
     208                    gens = gens.gens()
     209                else:
     210                    gens = [gens]
     211        from function_field_ideal import ideal_with_gens
     212        return ideal_with_gens(self, gens)
     213
     214class FunctionFieldOrder_basis(FunctionFieldOrder):
     215    """
     216    An order given by a basis over the maximal order of the base
     217    field.
     218    """
     219    def __init__(self, basis, check=True):
     220        """
     221        EXAMPLES::
     222
     223            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     224            sage: L.<y> = K.extension(y^4 + x*y + 4*x + 1)
     225            sage: O = L.equation_order(); O
     226            Order in Function field in y defined by y^4 + x*y + 4*x + 1
     227            sage: type(O)
     228            <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_basis_with_category'>
     229
     230        The basis only defines an order if the module it generates is closed under multiplication
     231         and contains the identity element (only checked when ``check`` is True)::
     232
     233            sage: K.<x> = FunctionField(QQ)
     234            sage: R.<y> = K[]
     235            sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x));
     236            sage: y.is_integral()
     237            False
     238            sage: L.order(y)
     239            Traceback (most recent call last):
     240            ...
     241            ValueError: The module generated by basis [1, y, y^2, y^3, y^4] must be closed under multiplication
     242           
     243        The basis also has to be linearly independent and of the same rank as the degree of the function field of its elements (only checked when ``check`` is True)::
     244
     245            sage: L.order(L(x))
     246            Traceback (most recent call last):
     247            ...
     248            ValueError: Basis [1, x, x^2, x^3, x^4] is not linearly independent
     249            sage: sage.rings.function_field.function_field_order.FunctionFieldOrder_basis([y,y,y^3,y^4,y^5])
     250            Traceback (most recent call last):
     251            ...
     252            ValueError: Basis [y, y, y^3, y^4, 2*x*y + (x^4 + 1)/x] is not linearly independent
     253        """
     254        if len(basis) == 0:
     255            raise ValueError, "basis must have positive length"
     256       
     257        fraction_field = basis[0].parent()
     258        if len(basis) != fraction_field.degree():
     259            raise ValueError, "length of basis must equal degree of field"
     260       
     261        FunctionFieldOrder.__init__(self, fraction_field)
     262       
     263        self._basis = tuple(basis)
     264        V, fr, to = fraction_field.vector_space()
     265        R = fraction_field.base_field().maximal_order()
     266        self._module = V.span([to(b) for b in basis], base_ring=R)
     267        self._ring = fraction_field.polynomial_ring()
     268        self._populate_coercion_lists_(coerce_list=[self._ring])
     269        if check:
     270            if self._module.rank() != fraction_field.degree():
     271                raise ValueError, "Basis %s is not linearly independent"%(basis)
     272            if not to(fraction_field(1)) in self._module:
     273                raise ValueError, "The identity element must be in the module spanned by basis %s"%(basis)
     274            if not all(to(a*b) in self._module for a in basis for b in basis):
     275                raise ValueError, "The module generated by basis %s must be closed under multiplication"%(basis)
     276        IntegralDomain.__init__(self, self, names = fraction_field.variable_names(), normalize = False)
     277
     278    def _element_constructor_(self, f, check=True):
     279        """
     280        Make ``f`` into an element of this order.
     281
     282        INPUT::
     283
     284            - ``f`` -- the element
     285            - ``check`` -- check if the element is in the order
     286
     287        EXAMPLES::
     288
     289            sage: K.<x> = FunctionField(QQ)
     290            sage: K.maximal_order()._element_constructor_(x)
     291            x
     292        """
     293        fraction_field=self.fraction_field()
     294       
     295        if f.parent() is fraction_field:
     296            f = f.element()
     297        f = self._ring(f)
     298        if check:
     299            V, fr, to = fraction_field.vector_space()
     300            f_vector = to(fraction_field(f))
     301            if not f_vector in self._module:
     302                raise ValueError, "%s is not an element of %s"%(f_vector,self)
     303        return fraction_field._element_class(self, f)
     304
     305    def fraction_field(self):
     306        """
     307        Returns the function field in which this is an order.
     308
     309        EXAMPLES::
     310
     311            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     312            sage: L.<y> = K.extension(y^4 + x*y + 4*x + 1)
     313            sage: O = L.equation_order()
     314            sage: O.fraction_field()
     315            Function field in y defined by y^4 + x*y + 4*x + 1
     316        """
     317        return self._fraction_field
     318
     319    def polynomial(self):
     320        """
     321        Returns the defining polynomial of the function field of which this is an order.
     322       
     323        EXAMPLES::
     324
     325            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     326            sage: L.<y> = K.extension(y^4 + x*y + 4*x + 1)
     327            sage: O = L.equation_order()
     328            sage: O.polynomial()
     329            y^4 + x*y + 4*x + 1
     330        """
     331        return self._fraction_field.polynomial()
     332
     333    def basis(self):
     334        """
     335        Returns a basis of self over the maximal order of the base field.
     336
     337        EXAMPLES::
     338
     339            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     340            sage: L.<y> = K.extension(y^4 + x*y + 4*x + 1)
     341            sage: O = L.equation_order()
     342            sage: O.basis()
     343            (1, y, y^2, y^3)
     344        """
     345        return self._basis
     346
     347    def free_module(self):
     348        """
     349        Returns the free module formed by the basis over the maximal order of the base field.
     350
     351        EXAMPLES::
     352
     353            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     354            sage: L.<y> = K.extension(y^4 + x*y + 4*x + 1)
     355            sage: O = L.equation_order()
     356            sage: O.free_module()
     357            Free module of degree 4 and rank 4 over Maximal order in Rational function field in x over Finite Field of size 7
     358            Echelon basis matrix:
     359            [1 0 0 0]
     360            [0 1 0 0]
     361            [0 0 1 0]
     362            [0 0 0 1]       
     363        """
     364        return self._module
     365
     366class FunctionFieldOrder_rational(PrincipalIdealDomain, FunctionFieldOrder):
     367    """
     368    The maximal order in a rational function field.
     369    """
     370    def __init__(self, function_field):
     371        """
     372        EXAMPLES::
     373       
     374            sage: K.<t> = FunctionField(GF(19)); K
     375            Rational function field in t over Finite Field of size 19
     376            sage: R = K.maximal_order(); R
     377            Maximal order in Rational function field in t over Finite Field of size 19
     378            sage: type(R)
     379            <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_rational_with_category'>
     380        """
     381        FunctionFieldOrder.__init__(self, function_field)
     382        PrincipalIdealDomain.__init__(self, self, names = function_field.variable_names(), normalize = False)
     383        self._ring = function_field._ring
     384        self._populate_coercion_lists_(coerce_list=[self._ring])
     385        self._gen = self(self._ring.gen())
     386        self._basis = (self(1),)
     387
     388    def basis(self):
     389        """
     390        Returns the basis (=1) for this order as a module over the polynomial ring.
     391       
     392        EXAMPLES::
     393
     394            sage: K.<t> = FunctionField(GF(19))
     395            sage: O = K.maximal_order()
     396            sage: O.basis()
     397            (1,)
     398            sage: parent(O.basis()[0])
     399            Maximal order in Rational function field in t over Finite Field of size 19
     400        """
     401        return self._basis
     402
     403    def ideal(self, *gens):
     404        """
     405        Returns the fractional ideal generated by ``gens``.
     406
     407        EXAMPLES::
     408
     409            sage: K.<x> = FunctionField(QQ)
     410            sage: O = K.maximal_order()
     411            sage: O.ideal(x)
     412            Ideal (x) of Maximal order in Rational function field in x over Rational Field
     413            sage: O.ideal([x,1/x]) == O.ideal(x,1/x) # multiple generators may be given as a list
     414            True
     415            sage: O.ideal(x^3+1,x^3+6)
     416            Ideal (1) of Maximal order in Rational function field in x over Rational Field
     417            sage: I = O.ideal((x^2+1)*(x^3+1),(x^3+6)*(x^2+1)); I
     418            Ideal (x^2 + 1) of Maximal order in Rational function field in x over Rational Field
     419            sage: O.ideal(I)
     420            Ideal (x^2 + 1) of Maximal order in Rational function field in x over Rational Field
     421        """
     422        if len(gens) == 1:
     423            gens = gens[0]
     424            if not isinstance(gens, (list, tuple)):
     425                if is_Ideal(gens):
     426                    gens = gens.gens()
     427                else:
     428                    gens = (gens,)
     429        from function_field_ideal import ideal_with_gens
     430        return ideal_with_gens(self, gens)
     431
     432    def _repr_(self):
     433        """
     434        EXAMPLES::
     435           
     436            sage: FunctionField(QQ,'y').maximal_order()._repr_()
     437            'Maximal order in Rational function field in y over Rational Field'
     438        """
     439        return "Maximal order in %s"%self.fraction_field()
     440
     441    def gen(self, n=0):
     442        """
     443        Returns the ``n``-th generator of self. Since there is only one generator ``n`` must be 0.
     444
     445        EXAMPLES::
     446
     447            sage: O = FunctionField(QQ,'y').maximal_order()
     448            sage: O.gen()
     449            y
     450            sage: O.gen(1)
     451            Traceback (most recent call last):
     452            ...
     453            IndexError: Only one generator.
     454        """
     455        if n != 0: raise IndexError, "Only one generator."
     456        return self._gen
     457
     458    def ngens(self):
     459        """
     460        Returns 1, the number of generators of self.
     461
     462        EXAMPLES::
     463
     464            sage: FunctionField(QQ,'y').maximal_order().ngens()
     465            1
     466        """
     467        return 1
     468
     469    def _element_constructor_(self, f):
     470        """
     471        Make ``f`` into an element of this order.
     472
     473        EXAMPLES::
     474
     475            sage: K.<y> = FunctionField(QQ)
     476            sage: O = K.maximal_order()
     477            sage: O._element_constructor_(y)
     478            y
     479            sage: O._element_constructor_(1/y)
     480            Traceback (most recent call last):
     481            ...
     482            ValueError: `1/y` is not a member of `Maximal order in Rational function field in y over Rational Field`
     483        """
     484        if f.parent() is self.fraction_field():
     485            if not f.denominator() in self.fraction_field().constant_base_field():
     486                raise ValueError("`%s` is not a member of `%s`"%(f,self))
     487            f = f.element()
     488        from function_field_element import FunctionFieldElement_rational
     489        return FunctionFieldElement_rational(self, self._ring(f))
  • 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"""
     2Function Field Morphisms
     3
     4AUTHORS:
     5
     6- William Stein (2010): initial version
     7
     8- Julian Rueth (2011-09-14): refactored class hierarchy
     9
     10EXAMPLES::
     11
     12    sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     13    sage: K.hom(1/x)
     14    Morphism of function fields defined by x |--> 1/x
     15    sage: L.<y> = K.extension(y^2-x)
     16    sage: K.hom(y)
     17    Morphism of function fields defined by x |--> y
     18    sage: L.hom([y,x])
     19    Morphism of function fields defined by y |--> y,  x |--> x
     20    sage: L.hom([x,y])
     21    Traceback (most recent call last):
     22    ...
     23    ValueError: invalid morphism
     24"""
     25#*****************************************************************************
     26#       Copyright (C) 2010 William Stein <wstein@gmail.com>
     27#       Copyright (C) 2011 Julian Rueth <julian.rueth@gmail.com>
     28#
     29#  Distributed under the terms of the GNU General Public License (GPL)
     30#  as published by the Free Software Foundation; either version 2 of
     31#  the License, or (at your option) any later version.
     32#                  http://www.gnu.org/licenses/
     33#*****************************************************************************
     34
     35from sage.categories.morphism import Morphism
     36from sage.rings.morphism import RingHomomorphism
     37
     38class FunctionFieldIsomorphism(Morphism):
     39    r"""
     40    A base class for isomorphisms between function fields and
     41    vector spaces.
     42
     43    EXAMPLES::
     44
     45        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     46        sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     47        sage: V, f, t = L.vector_space()
     48        sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldIsomorphism)
     49        True
     50    """
     51    def _repr_type(self):
     52        """
     53        Return the type of this map (an isomorphism), for the purposes of printing out self. 
     54       
     55        EXAMPLES::
     56
     57            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     58            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     59            sage: V, f, t = L.vector_space()
     60            sage: f._repr_type()
     61            'Isomorphism'
     62        """
     63        return "Isomorphism"
     64
     65    def is_injective(self):
     66        """
     67        Return True, since this isomorphism is injective.
     68       
     69        EXAMPLES::
     70
     71            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     72            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     73            sage: V, f, t = L.vector_space()           
     74            sage: f.is_injective()
     75            True
     76        """
     77        return True
     78
     79    def is_surjective(self):
     80        """
     81        Return True, since this isomorphism is surjective.
     82       
     83        EXAMPLES::
     84
     85            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     86            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     87            sage: V, f, t = L.vector_space()           
     88            sage: f.is_surjective()
     89            True
     90        """
     91        return True
     92
     93class MapVectorSpaceToFunctionField(FunctionFieldIsomorphism):
     94    r"""
     95    An isomorphism from a vector space to a function field.
     96   
     97    EXAMPLES::
     98
     99        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     100        sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     101        sage: V, f, t = L.vector_space(); f
     102        Isomorphism morphism:
     103          From: Vector space of dimension 2 over Rational function field in x over Rational Field
     104          To:   Function field in y defined by y^2 - x*y + 4*x^3
     105    """
     106    def __init__(self, V, K):
     107        """
     108        EXAMPLES::
     109       
     110            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     111            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     112            sage: V, f, t = L.vector_space(); type(f)
     113            <class 'sage.rings.function_field.maps.MapVectorSpaceToFunctionField'>
     114        """
     115        self._V = V
     116        self._K = K
     117        self._R = K.polynomial_ring()
     118        from sage.categories.homset import Hom
     119        FunctionFieldIsomorphism.__init__(self, Hom(V, K))
     120
     121    def _call_(self, v):
     122        """
     123        EXAMPLES::
     124
     125            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     126            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     127            sage: V, f, t = L.vector_space()                       
     128            sage: f(x*V.0 + (1/x^3)*V.1)         # indirect doctest
     129            1/x^3*y + x
     130        """
     131        f = self._R(self._V(v).list())
     132        return self._K(f)
     133
     134    def domain(self):
     135        """
     136        Return the vector space which is the domain of this isomorphism.
     137
     138        EXAMPLES::
     139
     140            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     141            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     142            sage: V, f, t = L.vector_space()                                   
     143            sage: f.domain()
     144            Vector space of dimension 2 over Rational function field in x over Rational Field
     145        """
     146        return self._V
     147
     148    def codomain(self):
     149        """
     150        Return the function field which is the codomain of this isomorphism.
     151
     152        EXAMPLES::
     153
     154            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     155            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     156            sage: V, f, t = L.vector_space()                                   
     157            sage: f.codomain()
     158            Function field in y defined by y^2 - x*y + 4*x^3
     159        """
     160        return self._K
     161
     162class MapFunctionFieldToVectorSpace(FunctionFieldIsomorphism):
     163    """
     164    An isomorphism from a function field to a vector space.
     165   
     166    EXAMPLES::
     167
     168        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     169        sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     170        sage: V, f, t = L.vector_space(); t
     171        Isomorphism morphism:
     172          From: Function field in y defined by y^2 - x*y + 4*x^3
     173          To:   Vector space of dimension 2 over Rational function field in x over Rational Field
     174    """
     175    def __init__(self, K, V):
     176        """
     177        EXAMPLES::
     178
     179            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     180            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     181            sage: V, f, t = L.vector_space(); type(t)
     182            <class 'sage.rings.function_field.maps.MapFunctionFieldToVectorSpace'>
     183        """
     184        self._V = V
     185        self._K = K
     186        self._zero = K.base_ring()(0)
     187        self._n = K.degree()
     188        from sage.categories.homset import Hom
     189        FunctionFieldIsomorphism.__init__(self, Hom(K, V))
     190
     191    def domain(self):
     192        """
     193        Return the function field which is the domain of this isomorphism.
     194
     195        EXAMPLES::
     196
     197            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     198            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     199            sage: V, f, t = L.vector_space()                                   
     200            sage: t.domain()
     201            Function field in y defined by y^2 - x*y + 4*x^3
     202        """
     203        return self._K
     204
     205    def codomain(self):
     206        """
     207        Return the vector space which is the domain of this isomorphism.
     208
     209        EXAMPLES::
     210
     211            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     212            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     213            sage: V, f, t = L.vector_space()                                   
     214            sage: t.codomain()
     215            Vector space of dimension 2 over Rational function field in x over Rational Field       
     216        """
     217        return self._V
     218
     219    def _repr_type(self):
     220        """
     221        EXAMPLES::
     222
     223            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     224            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     225            sage: V, f, t = L.vector_space()
     226            sage: t._repr_type()
     227            'Isomorphism'
     228        """
     229        return "Isomorphism"
     230   
     231    def _call_(self, x):
     232        """
     233        EXAMPLES::
     234
     235            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     236            sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
     237            sage: V, f, t = L.vector_space()                                   
     238            sage: t(x + (1/x^3)*y)                       # indirect doctest
     239            (x, 1/x^3)
     240        """
     241        y = self._K(x)
     242        v = y.list()
     243        w = v + [self._zero]*(self._n - len(v))
     244        return self._V(w)
     245
     246class FunctionFieldMorphism(RingHomomorphism):
     247    r"""
     248    Base class for morphisms between function fields.
     249    """
     250    def __init__(self, parent, im_gen, base_morphism):
     251        """
     252        EXAMPLES::
     253
     254            sage: K.<x> = FunctionField(QQ)
     255            sage: f = K.hom(1/x); f
     256            Morphism of function fields defined by x |--> 1/x
     257            sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldMorphism)
     258            True
     259        """
     260        RingHomomorphism.__init__(self, parent)
     261
     262        self._im_gen = im_gen
     263        self._base_morphism = base_morphism
     264
     265    def is_injective(self):
     266        """
     267        Returns True since homomorphisms of fields are injective.
     268
     269        EXAMPLES::
     270
     271            sage: K.<x> = FunctionField(QQ)
     272            sage: f = K.hom(1/x); f
     273            Morphism of function fields defined by x |--> 1/x
     274            sage: f.is_injective()
     275            True
     276        """
     277        return True
     278
     279    def __repr__(self):
     280        """
     281        EXAMPLES::
     282
     283            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     284            sage: L.<y> = K.extension(y^3 + 6*x^3 + x)
     285            sage: f = L.hom(y*2)
     286            sage: f.__repr__()     
     287            'Morphism of function fields defined by y |--> 2*y'
     288        """
     289        return "Morphism of function fields defined by %s"%self._short_repr()
     290
     291    def _short_repr(self):
     292        """
     293        EXAMPLES::
     294
     295            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     296            sage: L.<y> = K.extension(y^3 + 6*x^3 + x)
     297            sage: f = L.hom(y*2)
     298            sage: f._short_repr()
     299            'y |--> 2*y'
     300        """
     301        a = '%s |--> %s'%(self.domain().gen(), self._im_gen)
     302        if self._base_morphism is not None:
     303            a += ',  ' + self._base_morphism._short_repr()
     304        return a
     305
     306class FunctionFieldMorphism_polymod(FunctionFieldMorphism):
     307    """
     308    Morphism from a finite extension of a function field to a function field.
     309
     310    EXAMPLES::
     311
     312        sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     313        sage: L.<y> = K.extension(y^2 - x)
     314        sage: f = L.hom(-y); f
     315        Morphism of function fields defined by y |--> -y   
     316    """
     317    def __init__(self, parent, im_gen, base_morphism):
     318        """
     319        EXAMPLES::
     320
     321            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     322            sage: L.<y> = K.extension(y^3 + 6*x^3 + x)
     323            sage: f = L.hom(y*2); f
     324            Morphism of function fields defined by y |--> 2*y
     325            sage: type(f)
     326            <class 'sage.rings.function_field.maps.FunctionFieldMorphism_polymod'>
     327            sage: factor(L.polynomial(), proof=False)
     328            y^3 + 6*x^3 + x
     329            sage: f(y).charpoly('y')
     330            y^3 + 6*x^3 + x
     331        """
     332        FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism)
     333        # Verify that the morphism is valid:
     334        R = self.codomain()['X']
     335        v = parent.domain().polynomial().list()
     336        if base_morphism is not None:
     337            v = [base_morphism(a) for a in v]
     338        f = R(v)
     339        if f(im_gen):
     340            raise ValueError, "invalid morphism"
     341   
     342    def _call_(self, x):
     343        """
     344        EXAMPLES::
     345
     346            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
     347            sage: L.<y> = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     348            sage: f(y/x + x^2/(x+1))            # indirect doctest
     349            2/x*y + x^2/(x + 1)
     350            sage: f(y)
     351            2*y
     352        """
     353        v = x.list()
     354        if self._base_morphism is not None:
     355            v = [self._base_morphism(a) for a in v]
     356        f = v[0].parent()['X'](v)
     357        return f(self._im_gen)
     358
     359class FunctionFieldMorphism_rational(FunctionFieldMorphism):
     360    """
     361    Morphism from a rational function field to a function field.
     362
     363    EXAMPLES::
     364
     365        sage: K.<x> = FunctionField(QQ)
     366        sage: f = K.hom(1/x); f
     367        Morphism of function fields defined by x |--> 1/x
     368    """
     369    def __init__(self, parent, im_gen):
     370        """
     371        EXAMPLES::
     372
     373            sage: K.<x> = FunctionField(GF(7))
     374            sage: f = K.hom(1/x); f
     375            Morphism of function fields defined by x |--> 1/x
     376            sage: type(f)
     377            <class 'sage.rings.function_field.maps.FunctionFieldMorphism_rational'>
     378        """
     379        FunctionFieldMorphism.__init__(self, parent, im_gen, None)
     380
     381    def _call_(self, x):
     382        """
     383        EXAMPLES::
     384
     385            sage: K.<x> = FunctionField(GF(7))
     386            sage: f = K.hom(1/x); f
     387            Morphism of function fields defined by x |--> 1/x
     388            sage: f(x+1)                          # indirect doctest
     389            (x + 1)/x
     390            sage: 1/x + 1
     391            (x + 1)/x       
     392        """
     393        a = x.element()
     394        return a.subs({a.parent().gen():self._im_gen})
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
    a b  
    24242424                X[i] = c
    24252425        return X
    24262426
    2427     def factor(self):
     2427    def factor(self, proof=True):
    24282428        r"""
    24292429        Return the factorization of self over the base ring of this
    24302430        polynomial. Factoring polynomials over
     
    24892489        that this method is called instead to factor univariate
    24902490        polynomials over this ring.  This facility can be used to
    24912491        easily extend polynomial factorization to work over new rings
    2492         you introduce::
     2492        you introduce. ::
    24932493
    24942494             sage: R.<x> = QQ[]
    24952495             sage: (x^2 + 1).factor()
    24962496             x^2 + 1
    2497              sage: QQ._factor_univariate_polynomial = lambda f: f.change_ring(CDF).factor()
     2497             sage: QQ._factor_univariate_polynomial = lambda f, proof: f.change_ring(CDF).factor()
    24982498             sage: fz = (x^2 + 1).factor(); fz # random order of factors, with noise
    24992499             (x - ... + I) * (x - I)
    25002500             sage: # Change noisy zero term which affects the order of factors:
     
    28212821        ## do better than a generic implementation, but probably not much better
    28222822        ## if there are many factors.
    28232823        ##       
     2824       
     2825        ## HUGE TODO, refactor the code below here such that this method will
     2826        ## have as only the following code
     2827        ##
     2828        ## R = self.parent().base_ring()
     2829        ## return R._factor_univariate_polynomial(self)
     2830        ##
     2831        ## in this way we can move the specific logic of factoring to the
     2832        ## self.parent().base_ring() and get rid of all the ugly
     2833        ## is_SomeType(R) checks and get way nicer structured code
     2834        ## 200 lines of spagetti code is just way to much!
    28242835
    28252836        if self.degree() < 0:
    28262837            raise ValueError, "factorization of 0 not defined"
     
    28292840
    28302841        R = self.parent().base_ring()
    28312842        if hasattr(R, '_factor_univariate_polynomial'):
    2832             return R._factor_univariate_polynomial(self)
     2843            return R._factor_univariate_polynomial(self,proof=proof)
    28332844
    28342845        G = None
    28352846        ch = R.characteristic()
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b  
    483483
    484484        - element_constructor -- A class or function that creates
    485485          elements of this Parent given appropriate input (can also be
    486           filled in later with ``_populate_coercion_lists_``
     486          filled in later with ``_populate_coercion_lists_``)
    487487
    488488        - gens -- Generators for this object (can also be filled in
    489489          later with ``_populate_generators_``)
     
    16211621           return self.Hom(codomain)(im_gens, check=check)
    16221622   
    16231623    #################################################################################
    1624     # New New Coercion support functionality
     1624    # New Coercion support functionality
    16251625    #################################################################################
    16261626   
    16271627    def _populate_coercion_lists_(self,
  • setup.py

    diff --git a/setup.py b/setup.py
    a b  
    968968
    969969                     'sage.rings',
    970970                     'sage.rings.finite_rings',
     971                     'sage.rings.function_field',
    971972                     'sage.rings.number_field',
    972973                     'sage.rings.padics',
    973974                     'sage.rings.polynomial',