Ticket #9054: trac_9054-review.patch

File trac_9054-review.patch, 39.8 KB (added by mderickx, 6 years ago)
  • sage/categories/function_fields.py

    # HG changeset patch
    # User Maarten Derickx <m.derickx.student@gmail.com>
    # Date 1315731017 -7200
    # Node ID 3367dcff37d65c6a9c373f5611598095f5eeccbc
    # Parent  4627017a30adf31f1080f09b3baf42f7f28d2587
    imported patch trac_9054_review.patch
    
    diff --git a/sage/categories/function_fields.py b/sage/categories/function_fields.py
    a b  
    1414from sage.categories.category import Category
    1515from sage.misc.cachefunc import cached_method
    1616from sage.categories.basic import Fields
    17 from sage.rings.field import is_Field
    1817
    1918class FunctionFields(Category):
    2019    r"""
     
    3130    TESTS::
    3231
    3332        sage: TestSuite(FunctionFields()).run()
     33
    3434    """
    3535
    3636    @cached_method
    3737    def super_categories(self):
    3838        """
     39        Returns the Category of which this is a direct sub-Category
     40        For a list off all super caategories see all_super_categories
     41
    3942        EXAMPLES::
    4043
    4144            sage: FunctionFields().super_categories()
    4245            [Category of fields]
     46
    4347        """
    4448        return[Fields()]
    4549
    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)
    5550
    5651    def _call_(self, x):
    5752        r"""
     
    6156        EXAMPLES::
    6257
    6358            sage: C = FunctionFields()
     59            sage: K.<x>=FunctionField(QQ)
     60            sage: C(K)
     61            Rational function field in x over Rational Field
     62            sage: Ky.<y> = K[]
     63            sage: L = K.extension(y^2-x)
     64            sage: C(L)
     65            Function field in y defined by y^2 - x
     66            sage: C(L.equation_order())
     67            Function field in y defined by y^2 - x
     68           
    6469
    6570        """
    6671        try:
  • sage/misc/sage_unittest.py

    diff --git a/sage/misc/sage_unittest.py b/sage/misc/sage_unittest.py
    a b  
    1313import unittest
    1414import sys
    1515import traceback
     16import misc
    1617
    1718class TestSuite(object):
    1819    """
     
    254255        In conjonction with ``%pdb on``, this allows for the debbuger
    255256        to jump directly to the first failure location.
    256257        """
     258        time = options.get('cputime')
    257259        if type(skip) == str:
    258260            skip = [skip]
    259261        else:
     
    270272                # TODO: improve pretty printing
    271273                # could use the doc string of the test method?
    272274                tester.info(tester._prefix+"running .%s() . . ."%method_name, newline = False)
     275                if time:
     276                    start_time = misc.cputime()
    273277                test_method = getattr(self._instance, method_name)
    274278                try:
    275279                    test_method(tester = tester)
    276                     tester.info(" pass")
     280                    tester.info(" pass", newline = not time)
     281                    if time:
     282                        tester.info(", cputime: %f"%misc.cputime(start_time))
    277283                except catch_exception as e:
    278284                    failed.append(method_name)
    279285                    if isinstance(e, TestSuiteFailure):
  • sage/rings/function_field/all.py

    diff --git a/sage/rings/function_field/all.py b/sage/rings/function_field/all.py
    a b  
    1 from function_field import is_FunctionField
    21from constructor import FunctionField
    32
    43
  • sage/rings/function_field/constructor.py

    diff --git a/sage/rings/function_field/constructor.py b/sage/rings/function_field/constructor.py
    a b  
    11import function_field
     2from sage.misc.cachefunc import cached_function
     3from sage.misc.decorators import sage_wraps
    24
    3 def FunctionField(X, names=None):
     5
     6def FunctionField(X,names):
    47    """
    5     Return the function field defined by X.
     8    Return the function field in one variable with constant field X. The function
     9    field returned is unique in the sence that if you call this function twice
     10    with the same base field and name then you get the same python object back.
     11
     12    INPUT:
     13
     14        - `X` -- a field; return the function field in one variable over X.
     15
     16        - ``names`` -- name of variable as a string or a tuple containg a string
     17   
     18    EXAMPLES::
     19
     20        sage: FunctionField(QQ,'alpha')
     21        Rational function field in alpha over Rational Field
     22        sage: K.<alpha> = FunctionField(GF(7)); K
     23        Rational function field in alpha over Finite Field of size 7
     24    """
     25    if not isinstance(names,tuple):
     26        names = (names,)
     27    return _FunctionField(X,names)
     28
     29
     30@cached_function
     31def _FunctionField(X, names):
     32    """
     33    Does exactly the same as FunctionField, but with the disadvantage that it
     34    cannot be used for Pickling since it is decorated.
    635
    736    INPUT:
    837
     
    1645        Rational function field in alpha over Rational Field
    1746        sage: K.<alpha> = FunctionField(GF(7)); K
    1847        Rational function field in alpha over Finite Field of size 7
     48
    1949    """
    2050    return function_field.RationalFunctionField(X, names=names)
     51
     52
     53def FunctionField_polymod_Constructor(polynomial, names):
     54    """
     55    Constructs a FunctionField_polymod instance. This function takes care
     56    that it's unique.
     57
     58    EXAMPLES::
     59
     60        sage: K.<x> = FunctionField(QQ)
     61        sage: R.<y>=K[]
     62        sage: y2 = y*1
     63        sage: y2 is y
     64        False
     65        sage: L.<w>=K.extension(x-y^2) #indirect doctest
     66        sage: M.<w>=K.extension(x-y2^2) #indirect doctest
     67        sage: L is M
     68        True
    2169   
     70    """
     71    from sage.rings.polynomial.all import is_Polynomial
     72    if polynomial.parent().ngens()>1 or not is_Polynomial(polynomial):
     73        raise TypeError, "polynomial must be univariate a polynomial"
     74    if names is None:
     75        names = (polynomial.variable_name(), )
     76    if not isinstance(names,tuple):
     77        names = (names,)
     78    return _FunctionField_polymod_Constructor(polynomial, names)
     79
     80@cached_function
     81def _FunctionField_polymod_Constructor(polynomial, names):
     82    """
     83    Does exactly the same as FunctionField_polymod, but with the disadvantage that it
     84    cannot be used for Pickling since it is decorated.
     85
     86   
     87    EXAMPLES::
     88
     89        sage: K.<x> = FunctionField(QQ)
     90        sage: R.<y>=K[]
     91        sage: y2 = y*1
     92        sage: y2 is y
     93        False
     94        sage: L.<w>=K.extension(x-y^2) #indirect doctest
     95        sage: M.<w>=K.extension(x-y2^2) #indirect doctest
     96        sage: L is M
     97        True
     98   
     99
     100    """
     101    return function_field.FunctionField_polymod(polynomial, names)
     102   
  • 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
    a b  
    99    sage: K.<x> = FunctionField(GF(5^2,'a')); K
    1010    Rational function field in x over Finite Field in a of size 5^2
    1111    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
     12    sage: L.<y> = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L
     13    Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x
     14    sage: y^2
     15    y^2
     16    sage: y^3
    1717    2*x*y + (x^4 + 1)/x
    1818    sage: a = 1/y; a
    19     (4*x/(4*x^4 + 4))*y^4 + 2*x^2/(4*x^4 + 4)
     19    (4*x/(4*x^4 + 4))*y^2 + 2*x^2/(4*x^4 + 4)
    2020    sage: a * y
    2121    1
    2222
     
    3030    sage: t^2
    3131    x*y
    3232    sage: 1/t
    33     ((1/(x^4 + 1))*y^4 + 2*x/(4*x^4 + 4))*t
     33    ((1/(x^4 + 1))*y^2 + 2*x/(4*x^4 + 4))*t
    3434    sage: M.base_field()
    35     Function field in y defined by y^5 + 3*x*y + (4*x^4 + 4)/x
     35    Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x
    3636    sage: M.base_field().base_field()
    3737    Rational function field in x over Finite Field in a of size 5^2
     38
     39TESTS::
     40
     41    sage: TestSuite(K).run() #long time
     42    sage: TestSuite(L).run() #long time
     43    sage: TestSuite(M).run() #long time
     44   
     45The following tow test suites do not pass '_test_elements' yet since
     46R.an_element() has a _test_category method wich it should not have.
     47It is not the fault of the function field code so this will
     48be fixed in another ticket.
     49    sage: TestSuite(R).run(skip = '_test_elements') #long time
     50    sage: TestSuite(S).run(skip = '_test_elements') #long time
     51
    3852   
    3953"""
    4054
    4155from sage.structure.category_object import CategoryObject
    42 from sage.rings.ring import Field
     56from sage.rings.ring import Field 
    4357from sage.rings.integer_ring import ZZ
    4458from sage.structure.parent_gens import ParentWithGens
     59from sage.structure.parent import Parent
    4560import function_field_element
    46 
     61import constructor
    4762from sage.categories.function_fields import FunctionFields
    4863CAT = FunctionFields()
    4964
     
    5570
    5671    EXAMPLES::
    5772   
    58         sage: from sage.rings.function_field.all import is_FunctionField
     73        sage: from sage.rings.function_field.function_field import is_FunctionField
    5974        sage: is_FunctionField(QQ)
    6075        False
    6176        sage: is_FunctionField(FunctionField(QQ,'t'))
     
    7489        sage: isinstance(K, sage.rings.function_field.function_field.FunctionField)
    7590        True
    7691    """
     92    def some_elements(self):
     93         #the number of ellements could be made bigger late rbut right now the
     94         #TestSuite(F).run() take to long with more elements.
     95         return (self.random_element() for i in xrange(3))
     96
    7797    def characteristic(self):
    7898        """
    7999        Return the characteristic of this function field.
     
    136156            sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1))
    137157            Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1)
    138158        """
    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)
     159        return constructor.FunctionField_polymod_Constructor(f, names)
    147160
    148161    def order_with_basis(self, basis, check=True):
    149162        """
     
    154167
    155168           - ``basis`` -- a list of elements of self
    156169           - ``check`` -- bool (default: True); if True, check that
    157              the basis is really linearly independent
     170             the basis is really linearly independent and that the
     171             module it spans is closed under multiplication, and
     172             contains the identity element.
    158173
    159174        OUTPUT:
    160175
     
    167182            Order in Function field in Y defined by y^3 + x^3 + 4*x + 1
    168183            sage: O.basis()
    169184            (1, Y, Y^2)
    170             sage: O = L.order_with_basis([x, x^2 + x*Y, (2/3)*Y^2]); O
     185
     186        Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it::
     187
     188            sage: O = L.order_with_basis([1+Y, Y, Y^2]); O
    171189            Order in Function field in Y defined by y^3 + x^3 + 4*x + 1
    172190            sage: O.basis()
    173             (x, x*Y + x^2, 2/3*Y^2)
     191            (Y + 1, Y, Y^2)
     192       
     193
     194        The following error is raised when the module spanned by the basis is not closed under multiplication::
     195
     196            sage: O = L.order_with_basis([1, x^2 + x*Y, (2/3)*Y^2]); O
     197            Traceback (most recent call last):
     198            ...
     199            ValueError: The module generated by basis [1, x*Y + x^2, 2/3*Y^2] must be closed under multiplication
     200           
     201        and this happens when the identity is not in the module spanned by the basis::
     202
     203            sage: O = L.order_with_basis([x, x^2 + x*Y, (2/3)*Y^2])
     204            Traceback (most recent call last):
     205            ...
     206            ValueError: The identity element must be in the module spanned by basis [x, x*Y + x^2, 2/3*Y^2]
     207           
     208
    174209        """
    175210        from function_field_order import FunctionFieldOrder_basis
    176211        return FunctionFieldOrder_basis([self(a) for a in basis], check=check)
     
    289324            sage: L.hom([-y, x])
    290325            Morphism of function fields defined by y |--> -y,  x |--> x
    291326
     327        The usage of the keyword base_morphism is not implemented yet::
     328
     329            sage: L.hom([-y, x-1], base_morphism=phi)
     330            Traceback (most recent call last):
     331            ...
     332            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.
     333           
     334               
    292335        We make another extension of a rational function field::
    293336       
    294337            sage: R2.<t> = FunctionField(QQ); S2.<w> = R2[]
    295338            sage: L2.<w> = R2.extension((4*w)^2 - (t+1)^3 - 1)
    296339
    297         We define a morphism, by givin the images of generators::
     340        We define a morphism, by giving the images of generators::
    298341       
    299342            sage: f = L.hom([4*w, t+1]); f
    300343            Morphism of function fields defined by y |--> 4*w,  x |--> t + 1
     
    315358
    316359            sage: g = L3.hom([x,y]); g
    317360            Morphism of function fields defined by xx |--> x, yy |--> y
     361
    318362        """
     363        if base_morphism is not None:
     364            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." 
     365       
    319366        if not isinstance(im_gens, (list,tuple)):
    320367            im_gens = [im_gens]
    321368        if len(im_gens) == 0:
     
    368415        Rational Field
    369416        sage: M.constant_base_field()
    370417        Rational Field
     418
     419    .. WARNING::
     420
     421        It is not checked if the polynomial used to define this function field is irriducible
     422        Hence it is not guaranteed that this object really is a field!
     423        This is illustrated below.
     424
     425    ::
     426
     427        sage: K.<x>=FunctionField(QQ)
     428        sage: R.<y> = K[]
     429        sage: L.<w>=K.extension(x^2-y^2)
     430        sage: (w-x)*(w+x)
     431        0
     432        sage: 1/(w-x)
     433        1
     434        sage: w-x==0; w+x==0
     435        False
     436        False
     437       
    371438    """
    372     def __init__(self, polynomial, names, category=CAT):
     439    def __init__(self, polynomial, names,
     440            element_class = function_field_element.FunctionFieldElement_polymod,
     441            category=CAT):
    373442        """
    374443        Create a function field defined as an extension of another
    375444        function field by adjoining a root of a univariate polynomial.
     
    397466       
    398467            sage: L.<w> = K.extension(y^5 - x^3 - 3*x + x*y); L
    399468            Function field in w defined by y^5 + x*y - x^3 - 3*x
     469
    400470        """
    401471        from sage.rings.polynomial.all import is_Polynomial
     472        if polynomial.parent().ngens()>1 or not is_Polynomial(polynomial):
     473            raise TypeError, "polynomial must be univariate a polynomial"
    402474        if names is None:
    403475            names = (polynomial.variable_name(), )
    404         if not is_Polynomial(polynomial):
    405             raise TypeError, "polynomial must be a polynomial"
    406476        if polynomial.degree() <= 0:
    407477            raise ValueError, "polynomial must have positive degree"
    408478        base_field = polynomial.base_ring()
    409479        if not isinstance(base_field, FunctionField):
    410             raise TypeError, "polynomial must be over a function"
     480            raise TypeError, "polynomial must be over a FunctionField"
     481        self._element_class = element_class
     482        self._element_init_pass_parent = False
    411483        self._base_field = base_field
    412484        self._polynomial = polynomial
    413485       
    414         ParentWithGens.__init__(self, base_field,
     486        Field.__init__(self, base_field,
    415487                                names=names, category = category)
    416488
    417489        self._hash = hash(polynomial)
     
    419491        self._populate_coercion_lists_(coerce_list=[base_field, self._ring])
    420492        self._gen = self(self._ring.gen())
    421493
     494    def __reduce__(self):
     495        return  constructor.FunctionField_polymod_Constructor, (self._polynomial, self._names)
     496
     497
     498
    422499    def __hash__(self):
    423500        """
    424501        Return hash of this function field.
     
    463540            sage: from_A(to_A(1/alpha)) == 1/alpha
    464541            True           
    465542        """
    466         g, d = self._make_monic(self.polynomial())
     543        g, d = self._make_monic_integral(self.polynomial())
    467544        R = self.base_field()
    468545        K = R.extension(g, names=names)
    469546        to_K = self.hom(K.gen() / d)
    470547        from_K = K.hom(self.gen() * d)
    471548        return K, from_K, to_K
    472549
    473     def _make_monic(self, f):
     550    def _make_monic_integral(self, f):
    474551        r"""
    475552        Let alpha be a root of f.  This function returns a monic
    476553        integral polynomial g and an element d of the base field such
     
    480557       
    481558            sage: K.<x> = FunctionField(QQ); R.<y> = K[];
    482559            sage: L.<alpha> = K.extension(x^2*y^5 - 1/x)
    483             sage: g, d = L._make_monic(L.polynomial()); g,d
     560            sage: g, d = L._make_monic_integral(L.polynomial()); g,d
    484561            (y^5 - x^12, x^3)
     562            sage: (alpha*d).is_integral()
     563            True
     564            sage: g.is_monic()
     565            True
    485566            sage: g(alpha*d)
    486567            0
     568       
    487569        """
    488570        R = f.base_ring()
    489571        if not isinstance(R, RationalFunctionField):
     
    525607    def constant_base_field(self):
    526608        """
    527609        Return the constant field of the base rational function field.
    528                
     610                   
    529611        EXAMPLES::
    530612
    531613            sage: K.<x> = FunctionField(QQ); R.<y> = K[]
     
    533615            Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
    534616            sage: L.constant_base_field()
    535617            Rational Field
     618            sage: S.<z> = L[]
     619            sage: M.<z> = L.extension(z^2 - w)
     620            sage: M.constant_base_field()
     621            Rational Field
     622           
    536623        """
    537624        return self.base_field().constant_base_field()
    538625
     
    548635            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
    549636            Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
    550637            sage: L.degree()
    551             5       
     638            5       
     639             
    552640        """
    553641        return self._polynomial.degree()
    554642       
     
    562650            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
    563651            sage: L._repr_()
    564652            'Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x'
     653       
    565654        """
    566655        return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial)
    567656
     
    576665            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
    577666            sage: L.base_field()
    578667            Rational function field in x over Rational Field
     668       
    579669        """
    580670        return self._base_field
    581671
     672
    582673    def random_element(self, *args, **kwds):
    583674        """
    584675        Create a random element of this function field.  Parameters
     
    590681            sage: L.<w> = K.extension(y^2 - (x^2 + x))
    591682            sage: L.random_element() # random
    592683            ((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)
     684       
    593685        """
    594686        return self(self._ring.random_element(degree=self.degree(), *args, **kwds))
    595687
     
    605697            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
    606698            sage: L.polynomial()
    607699            y^5 - 2*x*y + (-x^4 - 1)/x
     700       
    608701        """
    609702        return self._polynomial
    610703
     
    620713            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
    621714            sage: L.polynomial_ring()
    622715            Univariate Polynomial Ring in y over Rational function field in x over Rational Field
     716       
    623717        """
    624718        return self._ring
    625719
     
    634728       
    635729        OUTPUT:
    636730
    637             -  ``V`` - a vector space over the rational numbers
     731            -  ``V`` - a vector space over base field
    638732            -  ``from_V`` - an isomorphism from V to self
    639733            -  ``to_V`` - an isomorphism from self to V
    640734
     
    685779            sage: v = x*V.0 + (1/x)*V.1
    686780            sage: to_V(from_V(v)) == v
    687781            True
     782
     783
     784        And we show how it works over an extension of an extension field.
     785
     786            sage: R2.<z> = L[]; M.<w> = L.extension(z^2 -y)
     787            sage: M.vector_space()
     788            (Vector space of dimension 2 over Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism map:
     789              From: Vector space of dimension 2 over Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x
     790              To:   Function field in w defined by z^2 - w, Isomorphism map:
     791              From: Function field in w defined by z^2 - w
     792              To:   Vector space of dimension 2 over Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x)
     793                   
    688794        """
    689795        try: return self._vector_space
    690796        except AttributeError:
     
    711817            Traceback (most recent call last):
    712818            ...
    713819            NotImplementedError
     820       
    714821        """
    715822        raise NotImplementedError
    716823
     
    756863            Traceback (most recent call last):
    757864            ...
    758865            IndexError: Only one generator.
     866
    759867        """
    760868        if n != 0: raise IndexError, "Only one generator."
    761869        return self._gen
     
    778886        """
    779887        If we view self as being presented as K[y]/(f(y)), then this
    780888        function returns the order generated by the class of y.  If f
    781         is not monic, then self._make_monic is called, and instead we
     889        is not monic, then self._make_monic_integral is called, and instead we
    782890        get the order generated by some integral multiple of a root of
    783891        alpha.
    784892       
     
    799907            Order in Function field in alpha defined by x^2*y^5 - 1/x
    800908            sage: O.basis()
    801909            (1, x^3*alpha, x^6*alpha^2, x^9*alpha^3, x^12*alpha^4)
     910       
    802911        """
    803         d = self._make_monic(self.polynomial())[1]
     912        d = self._make_monic_integral(self.polynomial())[1]
    804913        return self.order(d*self.gen(), check=False)
    805914   
    806915
     
    838947        sage: K.hom(L.gen())
    839948        Morphism of function fields defined by W |--> tbar
    840949    """
    841     def __init__(self, constant_field, names, category=CAT):
     950    def __init__(self, constant_field, names,
     951            element_class = function_field_element.FunctionFieldElement_rational,
     952            category=CAT):
    842953        """
    843954        Create a rational function field in one variable.
    844955
     
    870981            names = (names, )
    871982        if not constant_field.is_field():
    872983            raise TypeError, "constant_field must be a field"
    873         ParentWithGens.__init__(self, self, names=names, category = category)
     984        self._element_class = element_class
     985        self._element_init_pass_parent = False
     986        Field.__init__(self, self, names=names, category = category)
    874987        R = constant_field[names[0]]
    875988        self._hash = hash((constant_field, names))
    876989        self._constant_field = constant_field
     
    879992        self._populate_coercion_lists_(coerce_list=[self._field])
    880993        self._gen = self(R.gen())
    881994
     995    def __reduce__(self):
     996        return constructor.FunctionField, (self._constant_field, self._names)
     997   
    882998    def __hash__(self):
    883999        """
    8841000        Return hash of this function field.
     
    8881004            sage: K.<t> = FunctionField(QQ)
    8891005            sage: hash(K)
    8901006            502145503910697533              # 64-bit
    891             -500688323                      # 32-bit           
     1007            -500688323                      # 32-bit
     1008                       
    8921009        """
    8931010        return self._hash
    8941011
     
    9011018            sage: K.<t> = FunctionField(QQ)
    9021019            sage: K._repr_()
    9031020            'Rational function field in t over Rational Field'
     1021
    9041022        """
    9051023        return "Rational function field in %s over %s"%(
    9061024            self.variable_name(), self._constant_field)
     
    9241042            t
    9251043            sage: a.parent()
    9261044            Rational function field in t over Rational Field
     1045       
    9271046        """
     1047        #if isinstance(x, self._element_class):
     1048        #    if x.parent() is self:
     1049        #        return x
     1050        #    else:
     1051        #        return self._element_class(self, x)
     1052        #return self._element_class(self, x, y,
     1053        #        coerce=coerce, reduce = self.is_exact())
    9281054        if x.parent() is self._field:
    9291055            return function_field_element.FunctionFieldElement_rational(self, x)
    9301056        if isinstance(x, function_field_element.FunctionFieldElement):
     
    9531079            sage: S.<X> = R[]
    9541080            sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
    9551081            sage: R._to_bivariate_polynomial(f)
    956             (x^7*t^2 - x^4*t^5 - x^3 + t^3, t^3)       
     1082            (X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3)       
    9571083        """
    9581084        v = f.list()
    9591085        from sage.rings.arith import LCM
    9601086        denom = LCM([a.denominator() for a in v])
    9611087        S = denom.parent()
    962         x,t = S.base_ring()['x,t'].gens()
     1088        x,t = S.base_ring()['%s,%s'%(f.parent().variable_name(),self.variable_name())].gens()
    9631089        phi = S.hom([t])
    9641090        return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom
    9651091
     
    10041130            (1/t) * (X + (a + 2)*t)^3
    10051131            sage: f.factor(proof=False).prod() == f
    10061132            True
     1133
    10071134        """
    10081135        F, d = self._to_bivariate_polynomial(f)
    10091136        fac = F.factor(proof=proof)
     
    10331160            Univariate Polynomial Ring in x over Rational function field in x over Rational Field
    10341161            sage: K.polynomial_ring('T')
    10351162            Univariate Polynomial Ring in T over Rational function field in x over Rational Field
     1163       
    10361164        """
    10371165        if var != 'x': return self[var]
    10381166        try: return self._polynomial_ring
     
    10591187              To:   Rational function field in x over Rational Field, Isomorphism map:
    10601188              From: Rational function field in x over Rational Field
    10611189              To:   Vector space of dimension 1 over Rational function field in x over Rational Field)
     1190       
    10621191        """
    10631192        try: return self._vector_space
    10641193        except AttributeError:
     
    10781207
    10791208            sage: FunctionField(QQ,'alpha').random_element()
    10801209            (-1/2*alpha^2 - 4)/(-12*alpha^2 + 1/2*alpha - 1/95)
     1210       
    10811211        """
    10821212        return self(self._field.random_element(*args, **kwds))
    10831213
     
    10911221            sage: K.<t> = FunctionField(QQ)
    10921222            sage: K.degree()
    10931223            1
     1224       
    10941225        """
    10951226        return ZZ(1)
    10961227   
     
    11231254            sage: K.<t> = FunctionField(QQ)
    11241255            sage: K.ngens()
    11251256            1
     1257       
    11261258        """
    11271259        return 1
    11281260   
     
    11361268            sage: K.<t> = FunctionField(GF(7))
    11371269            sage: K.base_field()
    11381270            Rational function field in t over Finite Field of size 7
     1271       
    11391272        """
    11401273        return self
    11411274
     
    11711304            y^2 + y + 2
    11721305            sage: f(x^2)
    11731306            5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4       
     1307       
    11741308        """
    11751309        if isinstance(im_gens, CategoryObject):
    11761310            return self.Hom(im_gens).natural_map()
     
    11911325            sage: K.<t> = FunctionField(GF(7))
    11921326            sage: K.field()
    11931327            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1328       
    11941329        """
    11951330        return self._field
    11961331
     
    12071342            Maximal order in Rational function field in t over Rational Field
    12081343            sage: K.equation_order()
    12091344            Maximal order in Rational function field in t over Rational Field
     1345       
    12101346        """
    12111347        try: return self._maximal_order
    12121348        except AttributeError:
     
    12261362            sage: K.<t> = FunctionField(QQ)
    12271363            sage: K.constant_field()
    12281364            Rational Field
     1365       
    12291366        """
    12301367        return self._constant_field
    12311368
  • 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
    a b  
    1616    """
    1717    return isinstance(x, FunctionFieldElement)
    1818
     19def make_FunctionFieldElement(parent, element_class, representing_element):
     20    """
     21    Used for unpickling FunctionFieldElement objects (and subclasses).
     22   
     23    EXAMPLES::
     24   
     25        sage: from sage.rings.function_field.function_field_element import make_FunctionFieldElement
     26        sage: K.<x> = FunctionField(QQ)
     27        sage: make_FunctionFieldElement(K, K._element_class, (x+1)/x)
     28        (x + 1)/x
     29   
     30    """
     31    return element_class(parent, representing_element, reduce=False)
     32
    1933cdef class FunctionFieldElement(FieldElement):
    2034
    2135    cdef readonly object _x
     
    3145        True
    3246    """
    3347
     48    def __reduce__(self):
     49        """
     50        EXAMPLES::
     51       
     52            sage: K = FunctionField(QQ,'x')
     53            sage: f = K.random_element()
     54            sage: loads(f.dumps()) == f
     55            True
     56        """
     57        return (make_FunctionFieldElement,
     58                (self._parent, type(self), self._x))
     59
     60
    3461    cdef FunctionFieldElement _new_c(self):
    3562        cdef FunctionFieldElement x = <FunctionFieldElement>PY_NEW_SAME_TYPE(self)
    3663        x._parent = self._parent
     
    5279   
    5380    def matrix(self):
    5481        r"""
    55         Return the matrix of multiplication by self.
     82        Return the matrix of multiplication by self when seeing the function field
     83        of where self is an element of as a vectorspace over its base field.
    5684
    5785        EXAMPLES::
    5886
     
    82110            [          0           1           0]
    83111            [          0           0           1]
    84112            [         -x x*Y - 4*x^3           0]
     113
     114        We show that this matrix does indeed works as expected when making a
     115        vectorspace from a function field::
     116
     117            sage: K.<x>=FunctionField(QQ)
     118            sage: R.<y> = K[]
     119            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
     120            sage: V, from_V, to_V = L.vector_space()
     121            sage: w5 = to_V(w^5)
     122            sage: w5 = to_V(w^5); w5
     123            ((x^4 + 1)/x, 2*x, 0, 0, 0)
     124            sage: w4xw = to_V(w^4) * w.matrix(); w4xw
     125            ((x^4 + 1)/x, 2*x, 0, 0, 0)
     126            sage: w5 == w4xw
     127            True
     128       
    85129        """
    86130        if self._matrix is None:
    87131            # Multiply each power of field generator on the left by this
     
    206250        sage: x*Y + 1/x^3
    207251        x*Y + 1/x^3       
    208252    """
    209     def __init__(self, parent, x):
     253    def __init__(self, parent, x, reduce=True):
    210254        """
    211255        EXAMPLES::
    212256
     
    215259             <type 'sage.rings.function_field.function_field_element.FunctionFieldElement_polymod'>             
    216260        """
    217261        FieldElement.__init__(self, parent)
    218         self._x = x % self._parent.polynomial()
    219 
     262        if reduce:
     263            self._x = x % self._parent.polynomial()
     264        else:
     265            self._x = x
     266   
    220267    def element(self):
    221268        """
    222269        Return the underlying polynomial that represents this element.
     
    359406        sage: FunctionField(QQ, 't')
    360407        Rational function field in t over Rational Field
    361408    """
    362     def __init__(self, parent, x):
     409    def __init__(self, parent, x, reduce=True):
    363410        """
    364411        EXAMPLES::
    365412       
     
    368415        """
    369416        FieldElement.__init__(self, parent)
    370417        self._x = x
    371 
     418 
    372419    # nonoptimized
    373420
    374421    def element(self):
     
    615662            sage: (t*(x+1) - 1) in I
    616663            True           
    617664        """
     665        assert  len(I.gens()) == 1
    618666        f = I.gens()[0]._x
    619667        assert f.denominator() == 1
    620668        assert self._x.denominator() == 1
  • 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
    a b  
    134134            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
    135135            sage: I = M.ideal(y^3); J = M.ideal(y^2)
    136136            sage: Z = I.intersection(J); Z
    137             Ideal (6*x^6 + 5*x^3 + 6, (6*x^3 + 6)*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     137            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
    138138            sage: y^2 in Z
    139139            False
    140140            sage: y^3 in Z
     
    181181            sage: L.<y> = R.extension(y^2 - x^3 - 1); M = L.equation_order()   
    182182            sage: I = M.ideal(y)
    183183            sage: I.__invert__()
    184             Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     184            Ideal (6, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
    185185            sage: I^(-1)
    186             Ideal (1, (6/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     186            Ideal (6, (1/(x^3 + 1))*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
    187187            sage: I.__invert__() * I
    188             Ideal (1, 6*y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
     188            Ideal (1, y) of Order in Function field in y defined by y^2 + 6*x^3 + 6
    189189        """
    190190        if len(self.gens()) == 0:
    191191            raise ZeroDivisionError
  • 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
    a b  
    5959
    6060    def fraction_field(self):
    6161        """
     62        Returns the function field in wich this is an order
     63
    6264        EXAMPLES::
    6365
    6466            sage: FunctionField(QQ,'y').maximal_order().fraction_field()
     
    6668        """
    6769        return self._fraction_field
    6870
     71    function_field = fraction_field
     72   
    6973    def ideal_with_gens_over_base(self, gens):
    7074        """
    7175        Return the fractional ideal with given generators over the
     
    149153            sage: S
    150154            Order in Function field in Y defined by y^4 + x*y + 4*x + 1
    151155            sage: type(S)
    152             <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_basis'>
     156            <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_basis_with_category'>
     157
     158        The basis only defines an order if the module it generates is closed under multiplication
     159         and contains the identity element. This is only checked when check=True ::
     160
     161            sage: K.<x> = FunctionField(QQ)
     162            sage: R.<y> = K[]
     163            sage: L.<w> = K.extension(y^5 - (x^3 + 2*x*y + 1/x));
     164            sage: w.is_integral()
     165            False
     166            sage: L.order(w)
     167            Traceback (most recent call last):
     168            ...
     169            ValueError: The module generated by basis [1, w, w^2, w^3, w^4] must be closed under multiplication
     170           
     171        The basis also has to be linear independent and of the same rank as the degree of the function field of it's elements::
     172
     173            sage: L.order(L(x))
     174            Traceback (most recent call last):
     175            ...
     176            ValueError: Basis [1, x, x^2, x^3, x^4] is not linear independent
     177            sage: sage.rings.function_field.function_field_order.FunctionFieldOrder_basis([w,w,w^3,w^4,w^5])
     178            Traceback (most recent call last):
     179            ...
     180            ValueError: Basis [w, w, w^3, w^4, 2*x*w + (x^4 + 1)/x] is not linear independent
     181       
     182
    153183        """
    154184        if len(basis) == 0:
    155185            raise ValueError, "basis must have positive length"
     
    168198        self._populate_coercion_lists_(coerce_list=[self._ring])
    169199        if check:
    170200            if self._module.rank() != fraction_field.degree():
    171                 raise ValueError, "basis is not a basis"
     201                raise ValueError, "Basis %s is not linear independent"%(basis)
     202            if not to(fraction_field(1)) in self._module:
     203                raise ValueError, "The identity element must be in the module spanned by basis %s"%(basis)
     204            if not all(to(a*b) in self._module for a in basis for b in basis):
     205                raise ValueError, "The module generated by basis %s must be closed under multiplication"%(basis)
    172206        IntegralDomain.__init__(self, self, names = fraction_field.variable_names(), normalize = False)
    173207
    174     def _element_constructor_(self, f):
     208    def _element_constructor_(self, f, check=True):
    175209        """
    176210        EXAMPLES::
    177211
    178212            sage: R.<y> = FunctionField(QQ)
    179213            sage: R.maximal_order()._element_constructor_(y)
    180214            y
     215       
     216        If check=True test if the element is indeed in the order.
    181217        """
    182         # HUGE TODO: have to check that f is really in self!!
    183         if f.parent() is self.fraction_field():
     218        fraction_field=self.fraction_field()
     219       
     220        if f.parent() is fraction_field:
    184221            f = f.element()
    185         elif f.parent() is self._ring:
    186             return function_field_element.FunctionFieldElement_rational(self, f)
    187         return function_field_element.FunctionFieldElement_rational(self, self._ring(f))
     222        f = self._ring(f)
     223        if check:
     224            V, fr, to = fraction_field.vector_space()
     225            f_vector = to(fraction_field(f))
     226            if not f_vector in self._module:
     227                raise ValueError, "%s is not an element of %s"%(f_vector,self)
     228        return fraction_field._element_class(self, f)
    188229
    189230    def fraction_field(self):
    190231        """
     
    196237        """
    197238        return self._fraction_field
    198239
     240    def polynomial(self):
     241        """
     242        Returns the defining polynomial of the function field of which this is an order.
     243       
     244        EXAMPLES::
     245
     246            sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]; L.<Y> = K.extension(y^4 + x*y + 4*x + 1); S = L.equation_order()           
     247            sage: S.polynomial()
     248            y^4 + x*y + 4*x + 1
     249       
     250        """
     251        return self._fraction_field.polynomial()
     252
     253
    199254    def basis(self):
    200255        """
    201256        EXAMPLES::
     
    245300            sage: R = K.maximal_order(); R
    246301            Maximal order in Rational function field in t over Finite Field of size 19
    247302            sage: type(R)
    248             <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_rational'>
     303            <class 'sage.rings.function_field.function_field_order.FunctionFieldOrder_rational_with_category'>
    249304        """
    250305        FunctionFieldOrder.__init__(self, function_field)
    251306        IntegralDomain.__init__(self, self, names = function_field.variable_names(), normalize = False)
     
    268323            Maximal order in Rational function field in t over Finite Field of size 19
    269324        """
    270325        return self._basis
    271        
     326
    272327    def ideal(self, *gens):
    273328        """
    274329        Return the fractional ideal generated by the element gens or
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
    a b  
    27442744        ## do better than a generic implementation, but probably not much better
    27452745        ## if there are many factors.
    27462746        ##       
     2747       
     2748
     2749        ## HUGE TODO, refactor the code below here such that this method will
     2750        ## have as only the following code
     2751        ##
     2752        ## R=self.parent().base_ring()
     2753        ## return R._factor_polynomial(self)
     2754        ##
     2755        ## in this way we can move the specific logic of factoring to the
     2756        ## self.parent().base_ring() and get rid of all the ugly
     2757        ## is_SomeType(R) checks and get way nicer structured code       
     2758        ## 200 lines of spagetti code is just way to much!
    27472759
    27482760        if self.degree() < 0:
    27492761            raise ValueError, "factorization of 0 not defined"