Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Function Field Elements
AUTHORS:
- William Stein: initial version
- Robert Bradshaw (2010-05-27): cythonize function field elements
- Julian Rueth (2011-06-28): treat zero correctly
- Maarten Derickx (2011-09-11): added doctests, fixed pickling """ #***************************************************************************** # Copyright (C) 2010 William Stein <wstein@gmail.com> # Copyright (C) 2010 Robert Bradshaw <robertwb@math.washington.edu> # Copyright (C) 2011 Julian Rueth <julian.rueth@gmail.com> # Copyright (C) 2011 Maarten Derickx <m.derickx.student@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import
from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element from sage.misc.cachefunc import cached_method from sage.structure.richcmp cimport richcmp, richcmp_not_equal
def is_FunctionFieldElement(x): """ Return True if x is any type of function field element.
EXAMPLES::
sage: t = FunctionField(QQ,'t').gen() sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(t) True sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(0) False """
def make_FunctionFieldElement(parent, element_class, representing_element): """ Used for unpickling FunctionFieldElement objects (and subclasses).
EXAMPLES::
sage: from sage.rings.function_field.function_field_element import make_FunctionFieldElement sage: K.<x> = FunctionField(QQ) sage: make_FunctionFieldElement(K, K._element_class, (x+1)/x) (x + 1)/x """
cdef class FunctionFieldElement(FieldElement): """ The abstract base class for function field elements.
EXAMPLES::
sage: t = FunctionField(QQ,'t').gen() sage: isinstance(t, sage.rings.function_field.function_field_element.FunctionFieldElement) True """
cdef readonly object _x cdef readonly object _matrix
def __reduce__(self): """ EXAMPLES::
sage: K = FunctionField(QQ,'x') sage: f = K.random_element() sage: loads(f.dumps()) == f True """
cdef FunctionFieldElement _new_c(self):
def __pari__(self): r""" Coerce this element to PARI.
PARI does not know about general function field elements, so this raises an Exception.
TESTS:
Check that :trac:`16369` has been resolved::
sage: K.<a> = FunctionField(QQ) sage: R.<b> = K[] sage: L.<b> = K.extension(b^2-a) sage: b.__pari__() Traceback (most recent call last): ... NotImplementedError: PARI does not support general function field elements.
"""
def _latex_(self): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: latex((t+1)/t) \frac{t + 1}{t} sage: latex((t+1)/t^67) \frac{t + 1}{t^{67}} sage: latex((t+1/2)/t^67) \frac{t + \frac{1}{2}}{t^{67}} """
@cached_method def matrix(self, base=None): r""" Return the matrix of multiplication by this element, interpreting this element as an element of a vector space over ``base``.
INPUT:
- ``base`` -- a function field (default: ``None``), if ``None``, then the matrix is formed over the base field of this function field.
EXAMPLES:
A rational function field::
sage: K.<t> = FunctionField(QQ) sage: t.matrix() [t] sage: (1/(t+1)).matrix() [1/(t + 1)]
Now an example in a nontrivial extension of a rational function field::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: y.matrix() [ 0 1] [-4*x^3 x] sage: y.matrix().charpoly('Z') Z^2 - x*Z + 4*x^3
An example in a relative extension, where neither function field is rational::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: M.<T> = L[] sage: Z.<alpha> = L.extension(T^3 - y^2*T + x) sage: alpha.matrix() [ 0 1 0] [ 0 0 1] [ -x x*y - 4*x^3 0] sage: alpha.matrix(K) [ 0 0 1 0 0 0] [ 0 0 0 1 0 0] [ 0 0 0 0 1 0] [ 0 0 0 0 0 1] [ -x 0 -4*x^3 x 0 0] [ 0 -x -4*x^4 -4*x^3 + x^2 0 0] sage: alpha.matrix(Z) [alpha]
We show that this matrix does indeed work as expected when making a vector space from a function field::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) sage: V, from_V, to_V = L.vector_space() sage: y5 = to_V(y^5); y5 ((x^4 + 1)/x, 2*x, 0, 0, 0) sage: y4y = to_V(y^4) * y.matrix(); y4y ((x^4 + 1)/x, 2*x, 0, 0, 0) sage: y5 == y4y True """ # multiply each element of the vector space isomorphic to the parent # with this element; make matrix whose rows are the coefficients of the # result, and transpose
def trace(self): """ Return the trace of this function field element.
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: y.trace() x """
def norm(self): """ Return the norm of this function field element.
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: y.norm() 4*x^3
The norm is relative::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[] sage: M.<z> = L.extension(z^3 - y^2*z + x) sage: z.norm() -x sage: z.norm().parent() Function field in y defined by y^2 - x*y + 4*x^3 """
def characteristic_polynomial(self, *args, **kwds): """ Return the characteristic polynomial of this function field element. Give an optional input string to name the variable in the characteristic polynomial.
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[] sage: M.<z> = L.extension(z^3 - y^2*z + x) sage: x.characteristic_polynomial('W') W - x sage: y.characteristic_polynomial('W') W^2 - x*W + 4*x^3 sage: z.characteristic_polynomial('W') W^3 + (-x*y + 4*x^3)*W + x """
charpoly = characteristic_polynomial
def minimal_polynomial(self, *args, **kwds): """ Return the minimal polynomial of this function field element. Give an optional input string to name the variable in the characteristic polynomial.
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[] sage: M.<z> = L.extension(z^3 - y^2*z + x) sage: x.minimal_polynomial('W') W - x sage: y.minimal_polynomial('W') W^2 - x*W + 4*x^3 sage: z.minimal_polynomial('W') W^3 + (-x*y + 4*x^3)*W + x """
minpoly = minimal_polynomial
def is_integral(self): r""" Determine if self is integral over the maximal order of the base field.
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: y.is_integral() True sage: (y/x).is_integral() True sage: (y/x)^2 - (y/x) + 4*x 0 sage: (y/x^2).is_integral() False sage: (y/x).minimal_polynomial('W') W^2 - W + 4*x """
cdef class FunctionFieldElement_polymod(FunctionFieldElement): """ Elements of a finite extension of a function field.
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: x*y + 1/x^3 x*y + 1/x^3 """ def __init__(self, parent, x, reduce=True): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: type(y) <type 'sage.rings.function_field.function_field_element.FunctionFieldElement_polymod'> """ else: self._x = x
def element(self): """ Return the underlying polynomial that represents this element.
EXAMPLES:: sage: K.<x> = FunctionField(QQ); R.<T> = K[] sage: L.<y> = K.extension(T^2 - x*T + 4*x^3) sage: f = y/x^2 + x/(x^2+1); f 1/x^2*y + x/(x^2 + 1) sage: f.element() 1/x^2*y + x/(x^2 + 1) sage: type(f.element()) <class 'sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.element_class'> """
def _repr_(self): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: y._repr_() 'y' """
def __nonzero__(self): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: bool(y) True sage: bool(L(0)) False sage: bool(L.coerce(L.polynomial())) False """
def __hash__(self): """ TESTS::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: len({hash(y^i+x^j) for i in [-2..2] for j in [-2..2]}) == 25 True """
cpdef _richcmp_(self, other, int op): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: L(0) == 0 True sage: y != L(2) True """
cpdef _add_(self, right): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest (5*x + 5)*y + x/(x^3 + 1) sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest True sage: -y+y 0 """
cpdef _sub_(self, right): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest (-5*x - 1)*y + x/(x^3 + 1) sage: y-y 0 """
cpdef _mul_(self, right): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: y * (3*y + 5*x*y) # indirect doctest (5*x^2 + 3*x)*y - 20*x^4 - 12*x^3 """
cpdef _div_(self, right): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest 1 sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest Traceback (most recent call last): ... ZeroDivisionError: Cannot invert 0 """
def __invert__(self): """ EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: a = ~(2*y + 1/x); a # indirect doctest (-x^2/(8*x^5 + x^2 + 1/2))*y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1) sage: a*(2*y + 1/x) 1 """
def list(self): """ Return a list of coefficients of self, i.e., if self is an element of a function field K[y]/(f(y)), then return the coefficients of the reduced presentation as a polynomial in K[y].
EXAMPLES::
sage: K.<x> = FunctionField(QQ); R.<y> = K[] sage: L.<y> = K.extension(y^2 - x*y + 4*x^3) sage: a = ~(2*y + 1/x); a (-x^2/(8*x^5 + x^2 + 1/2))*y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1) sage: a.list() [(2*x^3 + x)/(16*x^5 + 2*x^2 + 1), -x^2/(8*x^5 + x^2 + 1/2)] sage: (x*y).list() [0, x] """
cdef class FunctionFieldElement_rational(FunctionFieldElement): """ Elements of a rational function field.
EXAMPLES::
sage: K.<t> = FunctionField(QQ); K Rational function field in t over Rational Field """ def __init__(self, parent, x, reduce=True): """ EXAMPLES::
sage: FunctionField(QQ,'t').gen()^3 t^3 """
def __pari__(self): r""" Coerce this element to PARI.
EXAMPLES::
sage: K.<a> = FunctionField(QQ) sage: ((a+1)/(a-1)).__pari__() (a + 1)/(a - 1)
"""
def element(self): """ Return the underlying fraction field element that represents this element.
EXAMPLES::
sage: K.<t> = FunctionField(GF(7)) sage: t.element() t sage: type(t.element()) <type 'sage.rings.fraction_field_FpT.FpTElement'>
sage: K.<t> = FunctionField(GF(131101)) sage: t.element() t sage: type(t.element()) <class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'> """
def list(self): """ Return a list of coefficients of self, i.e., if self is an element of a function field K[y]/(f(y)), then return the coefficients of the reduced presentation as a polynomial in K[y]. Since self is a member of a rational function field, this simply returns the list `[self]`
EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: t.list() [t] """
def _repr_(self): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: t._repr_() 't' """
def __nonzero__(self): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: bool(t) True sage: bool(K(0)) False sage: bool(K(1)) True """
def __hash__(self): """ TESTS:
It would be nice if the following would produce a list of 15 distinct hashes::
sage: K.<t> = FunctionField(QQ) sage: len({hash(t^i+t^j) for i in [-2..2] for j in [i..2]}) 10 """
cpdef _richcmp_(self, other, int op): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: t > 0 True sage: t < t^2 True """ cdef FunctionFieldElement left cdef FunctionFieldElement right return richcmp_not_equal(lp, rp, op) except TypeError: return NotImplemented
cpdef _add_(self, right): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: t + (3*t^3) # indirect doctest 3*t^3 + t """
cpdef _sub_(self, right): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: t - (3*t^3) # indirect doctest -3*t^3 + t """
cpdef _mul_(self, right): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: (t+1) * (t^2-1) # indirect doctest t^3 + t^2 - t - 1 """
cpdef _div_(self, right): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: (t+1) / (t^2 - 1) # indirect doctest 1/(t - 1) """
def numerator(self): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: f = (t+1) / (t^2 - 1/3); f (t + 1)/(t^2 - 1/3) sage: f.numerator() t + 1 """
def denominator(self): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: f = (t+1) / (t^2 - 1/3); f (t + 1)/(t^2 - 1/3) sage: f.denominator() t^2 - 1/3 """
def valuation(self, v): """ EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: f = (t-1)^2 * (t+1) / (t^2 - 1/3)^3 sage: f.valuation(t-1) 2 sage: f.valuation(t) 0 sage: f.valuation(t^2 - 1/3) -3 """
def is_square(self): """ Returns whether self is a square.
EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: t.is_square() False sage: (t^2/4).is_square() True sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square() True
sage: K.<t> = FunctionField(GF(5)) sage: (-t^2).is_square() True sage: (-t^2).sqrt() 2*t """
def sqrt(self, all=False): """ Returns the square root of self.
EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: f = t^2 - 2 + 1/t^2; f.sqrt() (t^2 - 1)/t sage: f = t^2; f.sqrt(all=True) [t, -t]
TESTS::
sage: K(4/9).sqrt() 2/3 sage: K(0).sqrt(all=True) [0] """ else:
def factor(self): """ Factor this rational function.
EXAMPLES::
sage: K.<t> = FunctionField(QQ) sage: f = (t+1) / (t^2 - 1/3) sage: f.factor() (t + 1) * (t^2 - 1/3)^-1 sage: (7*f).factor() (7) * (t + 1) * (t^2 - 1/3)^-1 sage: ((7*f).factor()).unit() 7 sage: (f^3).factor() (t + 1)^3 * (t^2 - 1/3)^-3 """
def inverse_mod(self, I): r""" Return an inverse of self modulo the integral ideal `I`, if defined, i.e., if `I` and self together generate the unit ideal.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: O = K.maximal_order(); I = O.ideal(x^2+1) sage: t = O(x+1).inverse_mod(I); t -1/2*x + 1/2 sage: (t*(x+1) - 1) in I True """ |