Ticket #9054: trac_9054-part10.patch

File trac_9054-part10.patch, 10.4 KB (added by was, 7 years ago)

morphisms of function fields

  • sage/rings/function_field/function_field.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1275044128 25200
    # Node ID c09927d141ce689ff0e3f6a4213869d6e9672f80
    # Parent  37ea57b6855e1262b342052382f9b761e03da4bd
    trac 9054 (part 10): morphisms of function fields
    
    diff -r 37ea57b6855e -r c09927d141ce sage/rings/function_field/function_field.py
    a b  
    204204            return True
    205205        return False
    206206
     207    def hom(self, im_gens, base_morphism=None):
     208        """
     209        Create a homomorphism from self to another function field.
     210       
     211        INPUT:
     212
     213           - ``im_gens`` -- a list of images of the generators of self
     214             and of successive base rings.
     215           
     216           - ``base_morphism`` -- (default: None) a homomorphism of
     217             the base ring, after the im_gens are used.  Thus if
     218             im_gens has length 2, then base_morphism should be a morphism
     219             from self.base_ring().base_ring().
     220
     221        EXAMPLES::
     222       
     223        We create a rational function field, and a quadratic extension of it::
     224       
     225            sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     226            sage: L.<y> = R.extension(y^2 - x^3 - 1)
     227
     228        We make the field automorphism that sends y to -y::
     229       
     230            sage: f = L.hom(-y); f
     231            Morphism of function fields defined by y |--> -y
     232
     233        Evaluation works::
     234       
     235            sage: f(y*x - 1/x)
     236            -x*y - 1/x
     237
     238        We try to define an invalid morphism::
     239       
     240            sage: f = L.hom(y+1); f
     241            Traceback (most recent call last):
     242            ...
     243            ValueError: invalid morphism
     244
     245        We make a morphism of the base rational function field::
     246       
     247            sage: phi = R.hom(x+1); phi
     248            Morphism of function fields defined by x |--> x + 1
     249            sage: phi(x^3 - 3)
     250            x^3 + 3*x^2 + 3*x - 2
     251            sage: (x+1)^3-3
     252            x^3 + 3*x^2 + 3*x - 2
     253
     254        We make a morphism by specifying where the generators and the
     255        base generators go::
     256       
     257            sage: L.hom([-y, x])
     258            Morphism of function fields defined by y |--> -y,  x |--> x
     259
     260        We make another extension of a rational function field::
     261       
     262            sage: R2.<t> = FunctionField(QQ); S2.<w> = R2[]
     263            sage: L2.<w> = R.extension((4*w)^2 - (t+1)^3 - 1)
     264
     265        We define a morphism, by givin the images of generators::
     266       
     267            sage: f = L.hom([4*w, t+1]); f
     268            Morphism of function fields defined by y |--> 4*w,  x |--> t + 1
     269
     270        Evaluation works, as expected::
     271       
     272            sage: f(y+x)
     273            4*w + t + 1
     274            sage: f(x*y + x/(x^2+1))
     275            (4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2)
     276        """
     277        if not isinstance(im_gens, (list,tuple)):
     278            im_gens = [im_gens]
     279        if len(im_gens) > 1:
     280            base_morphism = self.base_field().hom(im_gens[1:], base_morphism)
     281        return maps.FunctionFieldMorphism(self.Hom(im_gens[0].parent()), im_gens[0], base_morphism)
     282
    207283class FunctionField_polymod(FunctionField):
    208284    """
    209285    A function field defined by a univariate polynomial, as an
     
    901977        """
    902978        return self
    903979
     980    def hom(self, im_gens, base_morphism=None):
     981        """
     982        Create a homomorphism from self to another function field.
     983
     984        INPUT:
     985
     986            - ``im_gens`` -- exactly one element of some function field
     987            - ``base_morphism`` -- ignored
     988
     989        OUTPUT:
     990
     991            - a map between function fields
     992
     993        EXAMPLES::
     994
     995        We make a map from a rational function field to itself::
     996
     997            sage: R.<x> = FunctionField(GF(7))
     998            sage: R.hom( (x^4 + 2)/x)
     999            Morphism of function fields defined by x |--> (x^4 + 2)/x       
     1000       
     1001        We construct a map from a rational function field into a
     1002        non-rational extension field::
     1003       
     1004            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     1005            sage: L.<y> = R.extension(y^3 + 6*x^3 + x)
     1006            sage: f = R.hom(y^2 + y  + 2); f
     1007            Morphism of function fields defined by x |--> y^2 + y + 2
     1008            sage: f(x)
     1009            y^2 + y + 2
     1010            sage: f(x^2)
     1011            5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4       
     1012        """
     1013        if not isinstance(im_gens, (list,tuple)):
     1014            im_gens = [im_gens]
     1015        if len(im_gens) != 1:
     1016            raise ValueError, "there must be exactly one generator"
     1017        x = im_gens[0]
     1018        return maps.FunctionFieldMorphism_rational(self.Hom(x.parent()), x)
     1019
    9041020    def field(self):
    9051021        """
    9061022        Return the underlying field, forgetting the function field
  • sage/rings/function_field/maps.py

    diff -r 37ea57b6855e -r c09927d141ce sage/rings/function_field/maps.py
    a b  
    188188        v = y.list()
    189189        w = v + [self._zero]*(self._n - len(v))
    190190        return self._V(w)
     191
     192
     193##########################################################################
     194# Morphisms between function fields
     195
     196class FunctionFieldMorphism(Map):
     197    """
     198    EXAMPLES::
     199
     200        sage: R.<x> = FunctionField(QQ); S.<y> = R[]
     201        sage: L.<y> = R.extension(y^2 - x^2)
     202        sage: f = L.hom(-y); f
     203        Morphism of function fields defined by y |--> -y   
     204    """
     205    def __init__(self, parent, im_gen, base_morphism):
     206        """
     207        EXAMPLES::
     208
     209            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     210            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2); f
     211            Morphism of function fields defined by y |--> 2*y
     212            sage: type(f)
     213            <class 'sage.rings.function_field.maps.FunctionFieldMorphism'>
     214            sage: factor(L.polynomial())
     215            y^3 + 6*x^3 + x
     216            sage: f(y).charpoly('y')
     217            y^3 + 6*x^3 + x
     218        """
     219        self._im_gen = im_gen
     220        self._base_morphism = base_morphism
     221        Map.__init__(self, parent)
     222        # Verify that the morphism is valid:
     223        R = self.codomain()['X']
     224        v = parent.domain().polynomial().list()
     225        if base_morphism is not None:
     226            v = [base_morphism(a) for a in v]
     227        f = R(v)
     228        if f(im_gen):
     229            raise ValueError, "invalid morphism"
     230   
     231    def is_injective(self):
     232        """
     233        EXAMPLES::
     234
     235            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     236            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     237            sage: f.is_injective()
     238            True
     239        """
     240        return True
     241
     242    def __repr__(self):
     243        """
     244        EXAMPLES::
     245
     246            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     247            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     248            sage: f.__repr__()     
     249            'Morphism of function fields defined by y |--> 2*y'
     250        """
     251        return "Morphism of function fields defined by %s"%self._short_repr()
     252
     253    def __nonzero__(self):
     254        """
     255        EXAMPLES::
     256
     257            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     258            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     259            sage: f.__nonzero__()
     260            True
     261            sage: bool(f)
     262            True
     263        """
     264        return True
     265
     266    def _short_repr(self):
     267        """
     268        EXAMPLES::
     269
     270            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     271            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     272            sage: f._short_repr()
     273            'y |--> 2*y'
     274        """
     275        a = '%s |--> %s'%(self.domain().gen(), self._im_gen)
     276        if self._base_morphism is not None:
     277            a += ',  ' + self._base_morphism._short_repr()
     278        return a
     279   
     280    def _call_(self, x):
     281        """
     282        EXAMPLES::
     283
     284            sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
     285            sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
     286            sage: f(y/x + x^2/(x+1))            # indirect doctest
     287            2/x*y + x^2/(x + 1)
     288            sage: f(y)
     289            2*y
     290        """
     291        v = x.list()
     292        if self._base_morphism is not None:
     293            v = [self._base_morphism(a) for a in v]
     294        f = v[0].parent()['X'](v)
     295        return f(self._im_gen)
     296
     297class FunctionFieldMorphism_rational(FunctionFieldMorphism):
     298    def __init__(self, parent, im_gen):
     299        """
     300        EXAMPLES::
     301
     302            sage: R.<x> = FunctionField(GF(7)); f = R.hom(1/x); f
     303            Morphism of function fields defined by x |--> 1/x
     304            sage: type(f)
     305            <class 'sage.rings.function_field.maps.FunctionFieldMorphism_rational'>
     306        """
     307        Map.__init__(self, parent)
     308        self._im_gen = im_gen
     309        self._base_morphism = None
     310       
     311    def _call_(self, x):
     312        """
     313        EXAMPLES::
     314
     315            sage: R.<x> = FunctionField(GF(7)); f = R.hom(1/x); f
     316            Morphism of function fields defined by x |--> 1/x
     317            sage: f(x+1)                          # indirect doctest
     318            (x + 1)/x
     319            sage: 1/x + 1
     320            (x + 1)/x       
     321        """
     322        a = x.element()
     323        return a.subs({a.parent().gen():self._im_gen})
  • sage/rings/function_field/todo.txt

    diff -r 37ea57b6855e -r c09927d141ce sage/rings/function_field/todo.txt
    a b  
    11TODO:
    22
    3 [ ] isomorphisms between function fields:
    4      K.hom([top gen, next one down, etc.])
    5     make sure you include easy way to gens all the way down.
    6 
    7 [ ] Hess's algorithm
    8 [ ] reduction algorithm
     3[ ] Hess's RR spaces algorithm
    94[ ] factoring polynomials in n variables over rational function field
    105
     6[ ] reduction algorithm
    117[ ] new implementation of the function field API using Singular; for *speed*, but with less base rings supported...?
    12 
    138[ ] polynomial factoring of any univariate poly over a non-rational function field
    149
    1510[ ] checking irreducibility in FunctionField_polymod constructor
     
    2318
    2419
    2520DONE:
     21[x] isomorphisms between function fields:
     22     K.hom([top gen, next one down, etc.])
     23    make sure you include easy way to gens all the way down.
    2624[x] inverses of fractional ideals
    2725[x] factor for elements of the rational function field
    2826[x] ideals