Path: blob/master/src/sage/rings/function_field/maps.py
8820 views
r"""1Function Field Morphisms23AUTHORS:45- William Stein (2010): initial version67- Julian Rueth (2011-09-14): refactored class hierarchy89EXAMPLES::1011sage: K.<x> = FunctionField(QQ); R.<y> = K[]12sage: K.hom(1/x)13Morphism of function fields defined by x |--> 1/x14sage: L.<y> = K.extension(y^2-x)15sage: K.hom(y)16Morphism of function fields defined by x |--> y17sage: L.hom([y,x])18Morphism of function fields defined by y |--> y, x |--> x19sage: L.hom([x,y])20Traceback (most recent call last):21...22ValueError: invalid morphism23"""24#*****************************************************************************25# Copyright (C) 2010 William Stein <[email protected]>26# Copyright (C) 2011 Julian Rueth <[email protected]>27#28# Distributed under the terms of the GNU General Public License (GPL)29# as published by the Free Software Foundation; either version 2 of30# the License, or (at your option) any later version.31# http://www.gnu.org/licenses/32#*****************************************************************************3334from sage.categories.morphism import Morphism35from sage.rings.morphism import RingHomomorphism3637class FunctionFieldIsomorphism(Morphism):38r"""39A base class for isomorphisms between function fields and40vector spaces.4142EXAMPLES::4344sage: K.<x> = FunctionField(QQ); R.<y> = K[]45sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)46sage: V, f, t = L.vector_space()47sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldIsomorphism)48True49"""50def _repr_type(self):51"""52Return the type of this map (an isomorphism), for the purposes of printing out self.5354EXAMPLES::5556sage: K.<x> = FunctionField(QQ); R.<y> = K[]57sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)58sage: V, f, t = L.vector_space()59sage: f._repr_type()60'Isomorphism'61"""62return "Isomorphism"6364def is_injective(self):65"""66Return True, since this isomorphism is injective.6768EXAMPLES::6970sage: K.<x> = FunctionField(QQ); R.<y> = K[]71sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)72sage: V, f, t = L.vector_space()73sage: f.is_injective()74True75"""76return True7778def is_surjective(self):79"""80Return True, since this isomorphism is surjective.8182EXAMPLES::8384sage: K.<x> = FunctionField(QQ); R.<y> = K[]85sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)86sage: V, f, t = L.vector_space()87sage: f.is_surjective()88True89"""90return True9192class MapVectorSpaceToFunctionField(FunctionFieldIsomorphism):93r"""94An isomorphism from a vector space to a function field.9596EXAMPLES::9798sage: K.<x> = FunctionField(QQ); R.<y> = K[]99sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)100sage: V, f, t = L.vector_space(); f101Isomorphism morphism:102From: Vector space of dimension 2 over Rational function field in x over Rational Field103To: Function field in y defined by y^2 - x*y + 4*x^3104"""105def __init__(self, V, K):106"""107EXAMPLES::108109sage: K.<x> = FunctionField(QQ); R.<y> = K[]110sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)111sage: V, f, t = L.vector_space(); type(f)112<class 'sage.rings.function_field.maps.MapVectorSpaceToFunctionField'>113"""114self._V = V115self._K = K116self._R = K.polynomial_ring()117from sage.categories.homset import Hom118FunctionFieldIsomorphism.__init__(self, Hom(V, K))119120def _call_(self, v):121"""122EXAMPLES::123124sage: K.<x> = FunctionField(QQ); R.<y> = K[]125sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)126sage: V, f, t = L.vector_space()127sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest1281/x^3*y + x129"""130f = self._R(self._V(v).list())131return self._K(f)132133def domain(self):134"""135Return the vector space which is the domain of this isomorphism.136137EXAMPLES::138139sage: K.<x> = FunctionField(QQ); R.<y> = K[]140sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)141sage: V, f, t = L.vector_space()142sage: f.domain()143Vector space of dimension 2 over Rational function field in x over Rational Field144"""145return self._V146147def codomain(self):148"""149Return the function field which is the codomain of this isomorphism.150151EXAMPLES::152153sage: K.<x> = FunctionField(QQ); R.<y> = K[]154sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)155sage: V, f, t = L.vector_space()156sage: f.codomain()157Function field in y defined by y^2 - x*y + 4*x^3158"""159return self._K160161class MapFunctionFieldToVectorSpace(FunctionFieldIsomorphism):162"""163An isomorphism from a function field to a vector space.164165EXAMPLES::166167sage: K.<x> = FunctionField(QQ); R.<y> = K[]168sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)169sage: V, f, t = L.vector_space(); t170Isomorphism morphism:171From: Function field in y defined by y^2 - x*y + 4*x^3172To: Vector space of dimension 2 over Rational function field in x over Rational Field173"""174def __init__(self, K, V):175"""176EXAMPLES::177178sage: K.<x> = FunctionField(QQ); R.<y> = K[]179sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)180sage: V, f, t = L.vector_space(); type(t)181<class 'sage.rings.function_field.maps.MapFunctionFieldToVectorSpace'>182"""183self._V = V184self._K = K185self._zero = K.base_ring()(0)186self._n = K.degree()187from sage.categories.homset import Hom188FunctionFieldIsomorphism.__init__(self, Hom(K, V))189190def domain(self):191"""192Return the function field which is the domain of this isomorphism.193194EXAMPLES::195196sage: K.<x> = FunctionField(QQ); R.<y> = K[]197sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)198sage: V, f, t = L.vector_space()199sage: t.domain()200Function field in y defined by y^2 - x*y + 4*x^3201"""202return self._K203204def codomain(self):205"""206Return the vector space which is the domain of this isomorphism.207208EXAMPLES::209210sage: K.<x> = FunctionField(QQ); R.<y> = K[]211sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)212sage: V, f, t = L.vector_space()213sage: t.codomain()214Vector space of dimension 2 over Rational function field in x over Rational Field215"""216return self._V217218def _repr_type(self):219"""220EXAMPLES::221222sage: K.<x> = FunctionField(QQ); R.<y> = K[]223sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)224sage: V, f, t = L.vector_space()225sage: t._repr_type()226'Isomorphism'227"""228return "Isomorphism"229230def _call_(self, x):231"""232EXAMPLES::233234sage: K.<x> = FunctionField(QQ); R.<y> = K[]235sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)236sage: V, f, t = L.vector_space()237sage: t(x + (1/x^3)*y) # indirect doctest238(x, 1/x^3)239"""240y = self._K(x)241v = y.list()242w = v + [self._zero]*(self._n - len(v))243return self._V(w)244245class FunctionFieldMorphism(RingHomomorphism):246r"""247Base class for morphisms between function fields.248"""249def __init__(self, parent, im_gen, base_morphism):250"""251EXAMPLES::252253sage: K.<x> = FunctionField(QQ)254sage: f = K.hom(1/x); f255Morphism of function fields defined by x |--> 1/x256sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldMorphism)257True258"""259RingHomomorphism.__init__(self, parent)260261self._im_gen = im_gen262self._base_morphism = base_morphism263264def is_injective(self):265"""266Returns True since homomorphisms of fields are injective.267268EXAMPLES::269270sage: K.<x> = FunctionField(QQ)271sage: f = K.hom(1/x); f272Morphism of function fields defined by x |--> 1/x273sage: f.is_injective()274True275"""276return True277278def __repr__(self):279"""280EXAMPLES::281282sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]283sage: L.<y> = K.extension(y^3 + 6*x^3 + x)284sage: f = L.hom(y*2)285sage: f.__repr__()286'Morphism of function fields defined by y |--> 2*y'287"""288return "Morphism of function fields defined by %s"%self._short_repr()289290def _short_repr(self):291"""292EXAMPLES::293294sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]295sage: L.<y> = K.extension(y^3 + 6*x^3 + x)296sage: f = L.hom(y*2)297sage: f._short_repr()298'y |--> 2*y'299"""300a = '%s |--> %s'%(self.domain().gen(), self._im_gen)301if self._base_morphism is not None:302a += ', ' + self._base_morphism._short_repr()303return a304305class FunctionFieldMorphism_polymod(FunctionFieldMorphism):306"""307Morphism from a finite extension of a function field to a function field.308309EXAMPLES::310311sage: K.<x> = FunctionField(QQ); R.<y> = K[]312sage: L.<y> = K.extension(y^2 - x)313sage: f = L.hom(-y); f314Morphism of function fields defined by y |--> -y315"""316def __init__(self, parent, im_gen, base_morphism):317"""318EXAMPLES::319320sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]321sage: L.<y> = K.extension(y^3 + 6*x^3 + x)322sage: f = L.hom(y*2); f323Morphism of function fields defined by y |--> 2*y324sage: type(f)325<class 'sage.rings.function_field.maps.FunctionFieldMorphism_polymod'>326sage: factor(L.polynomial())327y^3 + 6*x^3 + x328sage: f(y).charpoly('y')329y^3 + 6*x^3 + x330"""331FunctionFieldMorphism.__init__(self, parent, im_gen, base_morphism)332# Verify that the morphism is valid:333R = self.codomain()['X']334v = parent.domain().polynomial().list()335if base_morphism is not None:336v = [base_morphism(a) for a in v]337f = R(v)338if f(im_gen):339raise ValueError, "invalid morphism"340341def _call_(self, x):342"""343EXAMPLES::344345sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]346sage: L.<y> = K.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)347sage: f(y/x + x^2/(x+1)) # indirect doctest3482/x*y + x^2/(x + 1)349sage: f(y)3502*y351"""352v = x.list()353if self._base_morphism is not None:354v = [self._base_morphism(a) for a in v]355f = v[0].parent()['X'](v)356return f(self._im_gen)357358class FunctionFieldMorphism_rational(FunctionFieldMorphism):359"""360Morphism from a rational function field to a function field.361362EXAMPLES::363364sage: K.<x> = FunctionField(QQ)365sage: f = K.hom(1/x); f366Morphism of function fields defined by x |--> 1/x367"""368def __init__(self, parent, im_gen):369"""370EXAMPLES::371372sage: K.<x> = FunctionField(GF(7))373sage: f = K.hom(1/x); f374Morphism of function fields defined by x |--> 1/x375sage: type(f)376<class 'sage.rings.function_field.maps.FunctionFieldMorphism_rational'>377"""378FunctionFieldMorphism.__init__(self, parent, im_gen, None)379380def _call_(self, x):381"""382EXAMPLES::383384sage: K.<x> = FunctionField(GF(7))385sage: f = K.hom(1/x); f386Morphism of function fields defined by x |--> 1/x387sage: f(x+1) # indirect doctest388(x + 1)/x389sage: 1/x + 1390(x + 1)/x391"""392a = x.element()393return a.subs({a.parent().gen():self._im_gen})394395396