Ticket #9054: trac_9054_function_fields_sd32.patch

File trac_9054_function_fields_sd32.patch, 71.4 KB (added by saraedum, 6 years ago)

Minimal support for functions field. Does not include all of the above patches.

  • module_list.py

    exporting patch:
    # HG changeset patch
    # User Julian Rueth <julian.rueth@gmail.com>
    Trac 9054: minimal function fields support
    
    diff --git a/module_list.py b/module_list.py
    index 09b997a..0b336f1 100644
    a b ext_modules = [ 
    13331333
    13341334        ################################
    13351335        ##
     1336        ## sage.rings.function_field
     1337        ##
     1338        ################################
     1339
     1340    Extension('sage.rings.function_field.function_field_element',
     1341              sources = ['sage/rings/function_field/function_field_element.pyx']),
     1342
     1343        ################################
     1344        ##
    13361345        ## sage.rings.number_field
    13371346        ##
    13381347        ################################
  • sage/categories/all.py

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

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

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

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

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

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

    diff --git a/setup.py b/setup.py
    index dc64797..1562241 100644
    a b code = setup(name = 'sage', 
    993993
    994994                     'sage.rings',
    995995                     'sage.rings.finite_rings',
     996                     'sage.rings.function_field',
    996997                     'sage.rings.number_field',
    997998                     'sage.rings.padics',
    998999                     'sage.rings.polynomial',