# Ticket #9054: trac_9054-part2.patch

File trac_9054-part2.patch, 26.1 KB (added by was, 11 years ago)
• ## sage/rings/function_field/all.py

```# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1274923579 25200
# Node ID c3dd4c08eaefb4782dc8bf946a611bfeb4fe5a82
# Parent  26b6d3b1b044522b123a231fbde7fd78409b9981
trac 9054 -- part 2: fully documented function fields; added vector space structure

diff -r 26b6d3b1b044 -r c3dd4c08eaef sage/rings/function_field/all.py```
 a from function_field import is_FunctionField, RationalFunctionField from function_field import is_FunctionField from constructor import FunctionField
• ## new file sage/rings/function_field/constructor.py

`diff -r 26b6d3b1b044 -r c3dd4c08eaef sage/rings/function_field/constructor.py`
 - import function_field def FunctionField(X, names=None): return function_field.RationalFunctionField(X, names=names)
• ## sage/rings/function_field/function_field.py

`diff -r 26b6d3b1b044 -r c3dd4c08eaef sage/rings/function_field/function_field.py`
 a We create an extension of a rational function fields, and do some simple arithmetic in it:: sage: K. = RationalFunctionField(GF(5^2,'a')); K sage: K. = FunctionField(GF(5^2,'a')); K Rational function field in x over Finite Field in a of size 5^2 sage: R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L """ from sage.rings.ring import Field from sage.rings.integer_ring import ZZ from sage.structure.parent_gens import ParentWithGens import function_field_element from sage.categories.function_fields import FunctionFields CAT = FunctionFields() import maps def is_FunctionField(x): """ Return True if x is of function field type. EXAMPLES: EXAMPLES:: sage: from sage.rings.function_field.all import is_FunctionField sage: is_FunctionField(QQ) False sage: is_FunctionField(FunctionField(QQ,'t')) True """ return isinstance(x, FunctionField) class FunctionField(Field): """ The abstract base class for all function fields. EXAMPLES:: sage: K. = FunctionField(QQ) sage: isinstance(K, sage.rings.function_field.function_field.FunctionField) True """ def extension(self, f, names=None): """ Create an extension L = K[y]/(f(y)) of a function field, defined by a univariate polynomial in one variable over this function field K. INPUT: - `f` -- a univariate polynomial over self - ``names`` -- None or string or length-1 tuple OUTPUT: - a function field EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: K.extension(y^5 - x^3 - 3*x + x*y) Function field in y defined by y^5 + x*y - x^3 - 3*x """ if names is None: names = f.variable_name() return FunctionField_polymod(f, names) class FunctionField_polymod(FunctionField): """ A function field defined by a univariate polynomial, as an extension of the base field. EXAMPLES:: We make a function field defined by a degree 5 polynomial over the rational function field over the rational numbers:: sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x We next make a function field over the above nontrivial function field L:: sage: S. = L[] sage: M. = L.extension(T^2 + w*T + y); M Function field in alpha defined by T^2 + w*T + w sage: 1/alpha ((x/(-x^4 - 1))*w^4 - 2*x^2/(-x^4 - 1))*alpha - 1 sage: alpha * (1/alpha) 1 We drill down the tower of function fields:: sage: M.base_field() Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x sage: M.base_field().base_field() Rational function field in x over Rational Field sage: M.base_field().base_field().constant_field() Rational Field sage: M.constant_field() Rational Field """ def __init__(self, polynomial, names, category=CAT): """ Create a function field defined as an extension of another function field by adjoining a root of a univariate polynomial. INPUT: - ``polynomial`` -- a univariate polynomial over a function field - ``names`` -- variable names (as a tuple of length 1 or string) - ``category`` -- a category (defaults to category of function fields) EXAMPLES:: We create an extension of function fields:: sage: K. = FunctionField(QQ); R. = K[] sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L Function field in y defined by y^5 + x*y - x^3 - 3*x Note the type:: sage: type(L) We can set the variable name, which doesn't have to be y:: sage: L. = K.extension(y^5 - x^3 - 3*x + x*y); L Function field in w defined by y^5 + x*y - x^3 - 3*x """ from sage.rings.polynomial.all import is_Polynomial if names is None: names = (polynomial.variable_name(), ) if not is_Polynomial(polynomial): raise TypeError, "polynomial must be a polynomial" if polynomial.degree() <= 0: raise ValueError, "polynomial must have positive degree" base_field = polynomial.base_ring() if not isinstance(base_field, FunctionField): raise TypeError, "polynomial must be over a function" self._base_field = base_field self._polynomial = polynomial self._free_module = base_field**polynomial.degree() ParentWithGens.__init__(self, base_field, names=(polynomial.variable_name(),), category = category) names=names, category = category) self._hash = hash((base_field, polynomial)) self._hash = hash(polynomial) self._ring = self._polynomial.parent() self._populate_coercion_lists_(coerce_list=[base_field, self._ring]) self._gen = self(self._ring.gen()) def __hash__(self): """ Return hash of this function field. EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L = K.extension(y^5 - x^3 - 3*x + x*y); hash(L) 3183366741743088279             # 64-bit ?                               # 32-bit """ return self._hash def constant_field(self): """ Return the constant field of this function field.  This is simply the constant field of the base field, which this function field is a finite extension of. EXAMPLES:: sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x sage: L.constant_field() Rational Field """ return self.base_field().constant_field() def degree(self): """ Return the degree of this function field over its base function field. EXAMPLES:: sage: K. = FunctionField(QQ) sage: R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x sage: L.degree() 5 """ return self._polynomial.degree() def _repr_(self): """ Return string representation of this function field. EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L._repr_() 'Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x' """ return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial) def base_field(self): """ Return the base field of this function field.  This function field is presented as L = K[y]/(f(y)), and the base field is by definition the field K. EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.base_field() Rational function field in x over Rational Field """ return self._base_field def polynomial(self): """ Return the univariate polynomial that defines this function field, i.e., the polynomial f(y) so that this function field is of the form K[y]/(f(y)). EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.polynomial() y^5 - 2*x*y + (-x^4 - 1)/x """ return self._polynomial def free_module(self): return self._free_module def polynomial_ring(self): """ Return the polynomial ring used to represents elements of this function field.  If we view this function field as being presented as K[y]/(f(y)), then this function returns the ring K[y]. EXAMPLES:: def ring_of_integers(self): sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.polynomial_ring() Univariate Polynomial Ring in y over Rational function field in x over Rational Field """ return self._ring def vector_space(self): """ Return a vector space V and isomorphisms self --> V and V --> self. This function allows us to identify the elements of self with elements of a vector space over the base field, which is useful for representation and arithmetic with orders, ideals, etc. OUTPUT: -  ``V`` - a vector space over the rational numbers -  ``from_V`` - an isomorphism from V to self -  ``to_V`` - an isomorphism from self to V EXAMPLES:: We define a function field:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x We get the vector spaces, and maps back and forth:: sage: V, from_V, to_V = L.vector_space() sage: V Vector space of dimension 5 over Rational function field in x over Rational Field sage: from_V Isomorphism map: From: Vector space of dimension 5 over Rational function field in x over Rational Field To:   Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x sage: to_V Isomorphism map: From: Function field in w defined by y^5 - 2*x*y + (-x^4 - 1)/x To:   Vector space of dimension 5 over Rational function field in x over Rational Field We convert an element of the vector space back to the function field:: sage: from_V(V.1) w We define an interesting element of the function field:: sage: a = 1/L.0; a (-x/(-x^4 - 1))*w^4 + 2*x^2/(-x^4 - 1) We convert it to the vector space, and get a vector over the base field:: sage: to_V(a) (2*x^2/(-x^4 - 1), 0, 0, 0, -x/(-x^4 - 1)) We convert to and back, and get the same element:: sage: from_V(to_V(a)) == a True In the other direction:: sage: v = x*V.0 + (1/x)*V.1 sage: to_V(from_V(v)) == v True """ try: return self._vector_space except AttributeError: V = self.base_field()**self.degree() from_V = maps.MapVectorSpaceToFunctionField(V, self) to_V   = maps.MapFunctionFieldToVectorSpace(self, V) self._vector_space = (V, from_V, to_V) return self._vector_space def maximal_order(self): """ Return the maximal_order of self.  If we view self as L = K[y]/(f(y)), then this is the ring of elements of L that are integral over K. EXAMPLES:: This is not yet implemented...:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.maximal_order() Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError def _element_constructor_(self, x): TESTS:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L._element_constructor_(L.polynomial_ring().gen()) w """ if x.parent() is self: return x def gen(self, n=0): """ Return the n-th generator of this function field.  By default n=0; any other value of n leads to an error.   The generator is the class of y, if we view self as being presented as K[y]/(f(y)). EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.gen() w sage: L.gen(1) Traceback (most recent call last): ... IndexError: Only one generator. """ if n != 0: raise IndexError, "Only one generator." return self._gen def ngens(self): return 1 """ Return the number of generators of this function field over its base field.  This is by definition 1. EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.ngens() 1 """ return ZZ(1) def equation_order(self): """ If we view self as being presented as K[y]/(f(y)), then this function returns the order generated by the class of y. EXAMPLES:: sage: K. = FunctionField(QQ); R. = K[] sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: L.equation_order() Traceback (most recent call last): ... NotImplementedError """ raise NotImplementedError class RationalFunctionField(FunctionField): def __init__(self, base_field, names, category=CAT): if not base_field.is_field(): raise TypeError, "base_field must be a field" ParentWithGens.__init__(self, base_field, names=names, category = category) R = base_field[names[0]] self._hash = hash((base_field, names)) self._base_field = base_field """ A rational function field K(t) in one variable, over an arbitrary base field. EXAMPLES:: sage: K. = FunctionField(GF(3)); K Rational function field in t over Finite Field of size 3 sage: K.gen() t sage: 1/t + t^3 + 5 (t^4 + 2*t + 1)/t There are various ways to get at the underlying fields and rings associated to a rational function field:: sage: K. = FunctionField(GF(7)) sage: K.base_field() Rational function field in t over Finite Field of size 7 sage: K.field() Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 sage: K.constant_field() Finite Field of size 7 sage: K.maximal_order() Univariate Polynomial Ring in t over Finite Field of size 7 """ def __init__(self, constant_field, names, category=CAT): """ Create a rational function field in one variable. INPUT: - ``constant_field`` -- an arbitrary field - ``names`` -- a string or tuple of length 1 - ``category`` -- default: FunctionFields() EXAMPLES:: sage: K. = FunctionField(CC); K Rational function field in t over Complex Field with 53 bits of precision sage: K.category() Category of function fields sage: FunctionField(QQ[I], 'alpha') Rational function field in alpha over Number Field in I with defining polynomial x^2 + 1 Must be over a field:: sage: FunctionField(ZZ) Traceback (most recent call last): ... TypeError: constant_field must be a field """ if not constant_field.is_field(): raise TypeError, "constant_field must be a field" ParentWithGens.__init__(self, self, names=names, category = category) R = constant_field[names[0]] self._hash = hash((constant_field, names)) self._constant_field = constant_field self._ring = R self._field = R.fraction_field() self._populate_coercion_lists_(coerce_list=[base_field]) self._populate_coercion_lists_(coerce_list=[self._field]) self._gen = self(R.gen()) def __hash__(self): """ Return hash of this function field. EXAMPLES:: sage: K. = FunctionField(QQ) sage: hash(K) 502145503910697533              # 64-bit ?                               # 32-bit """ return self._hash def _repr_(self): """ Return string representation of this function field. EXAMPLES:: sage: K. = FunctionField(QQ) sage: K._repr_() 'Rational function field in t over Rational Field' """ return "Rational function field in %s over %s"%( self.variable_name(), self._base_field) self.variable_name(), self._constant_field) def _element_constructor_(self, x): r""" Make x into an element of this function field, possibly not canonically. Coerce x into an element of this function field, possibly not canonically. INPUT: ``x``, as an element of this function field TESTS:: EXAMPLES:: sage: K. = FunctionField(QQ) sage: a = K._element_constructor_(K.maximal_order().gen()); a t sage: a.parent() Rational function field in t over Rational Field """ if x.parent() is self._field: return function_field_element.FunctionFieldElement_P1(self, x) raise TypeError return function_field_element.FunctionFieldElement_P1(self, self._field(x)) def degree(self): """ Return the degree over the base field of this rational function field, which is 1. EXAMPLES:: sage: K. = FunctionField(QQ) sage: K.degree() 1 """ return ZZ(1) def gen(self, n=0): """ Return the n-th generator of this function field.  If n is not 0, then an IndexError is raised. EXAMPLES:: sage: K. = FunctionField(QQ); K.gen() t sage: K.gen().parent() Rational function field in t over Rational Field sage: K.gen(1) Traceback (most recent call last): ... IndexError: Only one generator. """ if n != 0: raise IndexError, "Only one generator." return self._gen def ngens(self): return 1 """ Return the number of generators, which is 1. EXAMPLES:: sage: K. = FunctionField(QQ) sage: K.ngens() 1 """ return ZZ(1) def base_field(self): return self._base_field """ Return the base field of this rational function field, which is just this function field itself. EXAMPLES:: sage: K. = FunctionField(GF(7)) sage: K.base_field() Rational function field in t over Finite Field of size 7 """ return self def ring_of_integers(self): def field(self): """ Return the underlying field, forgetting the function field structure. EXAMPLES:: sage: K. = FunctionField(GF(7)) sage: K.field() Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 """ return self._field def maximal_order(self): """ Return the maximal order of this function field.  Since this is a rational function field it is of the form K(t), and the maximal order is by definition K[t]. EXAMPLES:: sage: K. = FunctionField(QQ) sage: K.maximal_order() Univariate Polynomial Ring in t over Rational Field """ return self._ring def field(self): return self._field def constant_field(self): """ Return the field that this rational function field is a transcendental extension of. EXAMPLES:: sage: K. = FunctionField(QQ) sage: K.constant_field() Rational Field """ return self._constant_field
• ## sage/rings/function_field/function_field_element.py

`diff -r 26b6d3b1b044 -r c3dd4c08eaef sage/rings/function_field/function_field_element.py`
 a self._x = x def _repr_(self): return repr(self._x) return self._x._repr(name=self.parent().variable_name()) def __nonzero__(self): return self._x.__nonzero__() def __invert__(self): P = self.parent() return P(self._x.xgcd(P._polynomial)[1]) def list(self): return self._x.padded_list(self.parent().degree()) class FunctionFieldElement_P1(FunctionFieldElement): def __init__(self, parent, x): FieldElement.__init__(self, parent) self._x = x def list(self): return [self] def _repr_(self): return repr(self._x)
• ## new file sage/rings/function_field/maps.py

`diff -r 26b6d3b1b044 -r c3dd4c08eaef sage/rings/function_field/maps.py`
 - r""" """ from sage.categories.map import Map from sage.categories.homset import Hom class FunctionFieldIsomorphism(Map): r""" A base class for various isomorphisms between function fields and vector spaces. """ def _repr_type(self): return "Isomorphism" def is_injective(self): return True def is_surjective(self): return True class MapVectorSpaceToFunctionField(FunctionFieldIsomorphism): r""" EXAMPLES: """ def __init__(self, V, K): self._V = V self._K = K self._R = K.polynomial_ring() FunctionFieldIsomorphism.__init__(self, Hom(V, K)) def _call_(self, v): f = self._R(self._V(v).list()) return self._K(f) def domain(self): return self._V def codomain(self): return self._K class MapFunctionFieldToVectorSpace(Map): def __init__(self, K, V): self._V = V self._K = K self._zero = K.base_ring()(0) self._n = K.degree() FunctionFieldIsomorphism.__init__(self, Hom(K, V)) def domain(self): return self._K def codomain(self): return self._V def _repr_type(self): return "Isomorphism" def _call_(self, x): y = self._K(x) v = y.list() w = v + [self._zero]*(self._n - len(v)) return self._V(w)
• ## new file sage/rings/function_field/todo.txt

`diff -r 26b6d3b1b044 -r c3dd4c08eaef sage/rings/function_field/todo.txt`
 - [ ] conversion back and forth between a free module over base [ ] Docstring headers for each file with description of content of file [ ] copyright headers [ ] polynomial factoring of any univariate poly over a function field: reduce to bivariate over constant field? [ ] checking irreducibility in FunctionField_polymod constructor [ ] pickle doctests [ ] TestSuite(s).run() doctests [ ] ideals [ ] non-monic defining polynomials [ ] 100% coverage [ ] matrix of element [ ] norm [ ] trace [ ] a command FunctionField to make a new function field from anything. [ ] method function_field() on algebraic curves, that give back a corresponding function field object. [ ]