Ticket #9054: trac_9054-part1.patch

File trac_9054-part1.patch, 12.5 KB (added by was, 7 years ago)
  • new file sage/categories/function_fields.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1274873455 25200
    # Node ID 26b6d3b1b044522b123a231fbde7fd78409b9981
    # Parent  9a6d51c550d5985150ac40546f8326ea9a87aec9
    trac 9054 -- create a class for basic function_field arithmetic for Sage
    
    diff -r 9a6d51c550d5 -r 26b6d3b1b044 sage/categories/function_fields.py
    - +  
     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 -r 9a6d51c550d5 -r 26b6d3b1b044 sage/rings/all.py
    a b  
    6767# Number field
    6868from number_field.all import *
    6969
     70# Function field
     71from function_field.all import *
     72
    7073# p-adic field
    7174from padics.all import *
    7275from padics.padic_printing import _printer_defaults as padic_printing
  • new file sage/rings/function_field/__init__.py

    diff -r 9a6d51c550d5 -r 26b6d3b1b044 sage/rings/function_field/__init__.py
    - +  
     1# Function fields
  • new file sage/rings/function_field/all.py

    diff -r 9a6d51c550d5 -r 26b6d3b1b044 sage/rings/function_field/all.py
    - +  
     1from function_field import is_FunctionField, RationalFunctionField
     2
     3
  • new file sage/rings/function_field/function_field.py

    diff -r 9a6d51c550d5 -r 26b6d3b1b044 sage/rings/function_field/function_field.py
    - +  
     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> = RationalFunctionField(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*y - x)
     28    sage: M
     29    Function field in t defined by y*t^2 + 4*x
     30    sage: t^2
     31    (4*x^2/(4*x^4 + 4))*y^4 + 2*x^3/(4*x^4 + 4)
     32    sage: 1/t
     33    4/(4*x)*y*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.rings.ring import Field
     42from sage.structure.parent_gens import ParentWithGens
     43import function_field_element
     44
     45from sage.categories.function_fields import FunctionFields
     46CAT = FunctionFields()
     47
     48def is_FunctionField(x):
     49    """
     50    Return True if x is of function field type.
     51
     52    EXAMPLES:
     53        sage: from sage.rings.function_field.all import is_FunctionField
     54        sage: is_FunctionField(QQ)
     55        False
     56    """
     57    return isinstance(x, FunctionField)
     58
     59
     60class FunctionField(Field):
     61    def extension(self, f, names=None):
     62        if names is None:
     63            names = f.variable_name()
     64        return FunctionField_polymod(f, names)
     65
     66class FunctionField_polymod(FunctionField):
     67    def __init__(self, polynomial, names, category=CAT):
     68        from sage.rings.polynomial.all import is_Polynomial
     69        if not is_Polynomial(polynomial):
     70            raise TypeError, "polynomial must be a polynomial"
     71        base_field = polynomial.base_ring()
     72        if not isinstance(base_field, FunctionField):
     73            raise TypeError, "polynomial must be over a function"
     74        self._base_field = base_field
     75        self._polynomial = polynomial
     76        self._free_module = base_field**polynomial.degree()
     77       
     78        ParentWithGens.__init__(self, base_field,
     79                                names=(polynomial.variable_name(),), category = category)
     80
     81        self._hash = hash((base_field, polynomial))
     82        self._ring = self._polynomial.parent()
     83        self._populate_coercion_lists_(coerce_list=[base_field, self._ring])
     84        self._gen = self(self._ring.gen())
     85       
     86       
     87    def _repr_(self):
     88        return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial)
     89
     90    def base_field(self):
     91        return self._base_field
     92
     93    def polynomial(self):
     94        return self._polynomial
     95
     96    def free_module(self):
     97        return self._free_module
     98
     99    def ring_of_integers(self):
     100        raise NotImplementedError
     101
     102    def _element_constructor_(self, x):
     103        r"""
     104        Make x into an element of this function field, possibly not canonically.
     105
     106        INPUT:
     107       
     108            - ``x`` - the element
     109         
     110        OUTPUT:
     111       
     112            ``x``, as an element of this function field
     113
     114        TESTS::
     115
     116        """
     117        if x.parent() is self:
     118            return x
     119
     120        if x.parent() is self._ring:
     121            return function_field_element.FunctionFieldElement_polymod(self, x)
     122       
     123        return function_field_element.FunctionFieldElement_polymod(self, self._ring(x))
     124   
     125
     126    def gen(self, n=0):
     127        if n != 0:
     128            raise IndexError, "Only one generator."
     129        return self._gen
     130
     131    def ngens(self):
     132        return 1
     133
     134    def equation_order(self):
     135        raise NotImplementedError
     136
     137class RationalFunctionField(FunctionField):
     138    def __init__(self, base_field, names, category=CAT):
     139        if not base_field.is_field():
     140            raise TypeError, "base_field must be a field"
     141        ParentWithGens.__init__(self, base_field, names=names, category = category)
     142        R = base_field[names[0]]
     143        self._hash = hash((base_field, names))
     144        self._base_field = base_field
     145        self._ring = R
     146        self._field = R.fraction_field()
     147        self._populate_coercion_lists_(coerce_list=[base_field])
     148        self._gen = self(R.gen())
     149
     150    def __hash__(self):
     151        return self._hash
     152
     153    def _repr_(self):
     154        return "Rational function field in %s over %s"%(
     155            self.variable_name(), self._base_field)
     156
     157    def _element_constructor_(self, x):
     158        r"""
     159        Make x into an element of this function field, possibly not canonically.
     160
     161        INPUT:
     162       
     163            - ``x`` - the element
     164         
     165        OUTPUT:
     166       
     167            ``x``, as an element of this function field
     168
     169        TESTS::
     170
     171        """
     172        if x.parent() is self._field:
     173            return function_field_element.FunctionFieldElement_P1(self, x)
     174        if isinstance(x, function_field_element.FunctionFieldElement):
     175            K = x.parent()
     176            if K is self:
     177                return x
     178            else:
     179                raise TypeError
     180        return function_field_element.FunctionFieldElement_P1(self, self._field(x))
     181
     182    def gen(self, n=0):
     183        if n != 0:
     184            raise IndexError, "Only one generator."
     185        return self._gen
     186
     187    def ngens(self):
     188        return 1
     189   
     190    def base_field(self):
     191        return self._base_field
     192
     193    def ring_of_integers(self):
     194        return self._ring
     195
     196    def field(self):
     197        return self._field
     198
     199
     200
     201
     202       
     203
     204   
     205
     206
  • new file sage/rings/function_field/function_field_element.py

    diff -r 9a6d51c550d5 -r 26b6d3b1b044 sage/rings/function_field/function_field_element.py
    - +  
     1from sage.structure.element import FieldElement
     2
     3class FunctionFieldElement(FieldElement):
     4    pass
     5
     6class FunctionFieldElement_polymod(FunctionFieldElement):
     7    def __init__(self, parent, x):
     8        FieldElement.__init__(self, parent)
     9        self._x = x
     10
     11    def _repr_(self):
     12        return repr(self._x)
     13       
     14    def __nonzero__(self):
     15        return self._x.__nonzero__()
     16
     17    def __cmp__(self, other):
     18        return cmp(self._x, other._x)
     19
     20    def _add_(self, right):
     21        return self.parent()(self._x + right._x)
     22
     23    def _sub_(self, right):
     24        return self.parent()(self._x - right._x)
     25
     26    def _mul_(self, right):
     27        P = self.parent()
     28        f = self._x * right._x
     29        return P(f.quo_rem(P._polynomial)[1])
     30
     31    def _div_(self, right):
     32        return self * ~right
     33
     34    def __invert__(self):
     35        P = self.parent()
     36        return P(self._x.xgcd(P._polynomial)[1])
     37   
     38
     39class FunctionFieldElement_P1(FunctionFieldElement):
     40    def __init__(self, parent, x):
     41        FieldElement.__init__(self, parent)
     42        self._x = x
     43
     44    def _repr_(self):
     45        return repr(self._x)
     46       
     47    def __nonzero__(self):
     48        return self._x.__nonzero__()
     49
     50    def __cmp__(self, other):
     51        return cmp(self._x, other._x)
     52
     53    def _add_(self, right):
     54        return self.parent()(self._x + right._x)
     55
     56    def _sub_(self, right):
     57        return self.parent()(self._x - right._x)
     58
     59    def _mul_(self, right):
     60        return self.parent()(self._x * right._x)
     61
     62    def _div_(self, right):
     63        return self.parent()(self._x / right._x)
  • sage/structure/parent.pyx

    diff -r 9a6d51c550d5 -r 26b6d3b1b044 sage/structure/parent.pyx
    a b  
    414414
    415415        - element_constructor -- A class or function that creates
    416416          elements of this Parent given appropriate input (can also be
    417           filled in later with ``_populate_coercion_lists_``
     417          filled in later with ``_populate_coercion_lists_``)
    418418
    419419        - gens -- Generators for this object (can also be filled in
    420420          later with ``_populate_generators_``)
     
    12251225           return self.Hom(codomain)(im_gens, check=check)
    12261226   
    12271227    #################################################################################
    1228     # New New Coercion support functionality
     1228    # New Coercion support functionality
    12291229    #################################################################################
    12301230   
    12311231    def _populate_coercion_lists_(self,
  • setup.py

    diff -r 9a6d51c550d5 -r 26b6d3b1b044 setup.py
    a b  
    883883
    884884                     'sage.rings',
    885885                     'sage.rings.finite_rings',
     886                     'sage.rings.function_field',
    886887                     'sage.rings.number_field',
    887888                     'sage.rings.padics',
    888889                     'sage.rings.polynomial',