Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241852 views
1
#################################################################################
2
#
3
# (c) Copyright 2010 William Stein
4
#
5
# This file is part of PSAGE
6
#
7
# PSAGE is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# PSAGE is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#
20
#################################################################################
21
22
23
r"""
24
25
"""
26
27
from sage.categories.map import Map
28
from sage.categories.homset import Hom
29
30
from function_field_order import FunctionFieldOrder
31
32
class FunctionFieldIsomorphism(Map):
33
r"""
34
A base class for various isomorphisms between function fields and
35
vector spaces.
36
37
EXAMPLES::
38
39
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
40
sage: V, f, t = L.vector_space()
41
sage: isinstance(f, sage.rings.function_field.maps.FunctionFieldIsomorphism)
42
True
43
"""
44
def _repr_type(self):
45
"""
46
Return the type of this map (an isomorphism), for the purposes of printing out self.
47
48
EXAMPLES::
49
50
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
51
sage: V, f, t = L.vector_space()
52
sage: f._repr_type()
53
'Isomorphism'
54
"""
55
return "Isomorphism"
56
57
def is_injective(self):
58
"""
59
Return True, since this isomorphism is injective.
60
61
EXAMPLES::
62
63
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
64
sage: V, f, t = L.vector_space()
65
sage: f.is_injective()
66
True
67
"""
68
return True
69
70
def is_surjective(self):
71
"""
72
Return True, since this isomorphism is surjective.
73
74
EXAMPLES::
75
76
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
77
sage: V, f, t = L.vector_space()
78
sage: f.is_surjective()
79
True
80
"""
81
return True
82
83
class MapVectorSpaceToFunctionField(FunctionFieldIsomorphism):
84
r"""
85
An isomorphism from a vector space and a function field.
86
87
EXAMPLES:
88
89
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
90
sage: V, f, t = L.vector_space(); f
91
Isomorphism map:
92
From: Vector space of dimension 2 over Rational function field in x over Rational Field
93
To: Function field in Y defined by y^2 - x*y + 4*x^3
94
"""
95
def __init__(self, V, K):
96
"""
97
EXAMPLES::
98
99
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
100
sage: V, f, t = L.vector_space(); type(f)
101
<class 'sage.rings.function_field.maps.MapVectorSpaceToFunctionField'>
102
"""
103
self._V = V
104
self._K = K
105
self._R = K.polynomial_ring()
106
FunctionFieldIsomorphism.__init__(self, Hom(V, K))
107
108
def _call_(self, v):
109
"""
110
EXAMPLES::
111
112
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
113
sage: V, f, t = L.vector_space()
114
sage: f(x*V.0 + (1/x^3)*V.1) # indirect doctest
115
1/x^3*Y + x
116
"""
117
f = self._R(self._V(v).list())
118
return self._K(f)
119
120
def domain(self):
121
"""
122
EXAMPLES::
123
124
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
125
sage: V, f, t = L.vector_space()
126
sage: f.domain()
127
Vector space of dimension 2 over Rational function field in x over Rational Field
128
"""
129
return self._V
130
131
def codomain(self):
132
"""
133
EXAMPLES::
134
135
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
136
sage: V, f, t = L.vector_space()
137
sage: f.codomain()
138
Function field in Y defined by y^2 - x*y + 4*x^3
139
"""
140
return self._K
141
142
143
class MapFunctionFieldToVectorSpace(FunctionFieldIsomorphism):
144
"""
145
An isomorphism from a function field to a vector space.
146
147
EXAMPLES::
148
149
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
150
sage: V, f, t = L.vector_space(); t
151
Isomorphism map:
152
From: Function field in Y defined by y^2 - x*y + 4*x^3
153
To: Vector space of dimension 2 over Rational function field in x over Rational Field
154
"""
155
def __init__(self, K, V):
156
"""
157
EXAMPLES::
158
159
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
160
sage: V, f, t = L.vector_space(); type(t)
161
<class 'sage.rings.function_field.maps.MapFunctionFieldToVectorSpace'>
162
"""
163
self._V = V
164
self._K = K
165
self._zero = K.base_ring()(0)
166
self._n = K.degree()
167
FunctionFieldIsomorphism.__init__(self, Hom(K, V))
168
169
def domain(self):
170
"""
171
EXAMPLES::
172
173
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
174
sage: V, f, t = L.vector_space()
175
sage: t.domain()
176
Function field in Y defined by y^2 - x*y + 4*x^3
177
"""
178
return self._K
179
180
def codomain(self):
181
"""
182
EXAMPLES::
183
184
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
185
sage: V, f, t = L.vector_space()
186
sage: t.codomain()
187
Vector space of dimension 2 over Rational function field in x over Rational Field
188
"""
189
return self._V
190
191
def _repr_type(self):
192
"""
193
EXAMPLES::
194
195
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
196
sage: V, f, t = L.vector_space()
197
sage: t._repr_type()
198
'Isomorphism'
199
"""
200
return "Isomorphism"
201
202
def _call_(self, x):
203
"""
204
EXAMPLES::
205
206
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
207
sage: V, f, t = L.vector_space()
208
sage: t(x + (1/x^3)*Y) # indirect doctest
209
(x, 1/x^3)
210
"""
211
y = self._K(x)
212
v = y.list()
213
w = v + [self._zero]*(self._n - len(v))
214
return self._V(w)
215
216
217
##########################################################################
218
# Morphisms between function fields
219
220
class FunctionFieldMorphism(Map):
221
"""
222
EXAMPLES::
223
224
sage: R.<x> = FunctionField(QQ); S.<y> = R[]
225
sage: L.<y> = R.extension(y^2 - x^2)
226
sage: f = L.hom(-y); f
227
Morphism of function fields defined by y |--> -y
228
"""
229
def __init__(self, parent, im_gen, base_morphism):
230
"""
231
EXAMPLES::
232
233
sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
234
sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2); f
235
Morphism of function fields defined by y |--> 2*y
236
sage: type(f)
237
<class 'sage.rings.function_field.maps.FunctionFieldMorphism'>
238
sage: factor(L.polynomial())
239
y^3 + 6*x^3 + x
240
sage: f(y).charpoly('y')
241
y^3 + 6*x^3 + x
242
"""
243
self._im_gen = im_gen
244
self._base_morphism = base_morphism
245
Map.__init__(self, parent)
246
# Verify that the morphism is valid:
247
R = self.codomain()['X']
248
v = parent.domain().polynomial().list()
249
if base_morphism is not None:
250
v = [base_morphism(a) for a in v]
251
f = R(v)
252
if f(im_gen):
253
raise ValueError, "invalid morphism"
254
255
def is_injective(self):
256
"""
257
EXAMPLES::
258
259
sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
260
sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
261
sage: f.is_injective()
262
True
263
"""
264
return True
265
266
def __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.__repr__()
273
'Morphism of function fields defined by y |--> 2*y'
274
"""
275
return "Morphism of function fields defined by %s"%self._short_repr()
276
277
def __nonzero__(self):
278
"""
279
EXAMPLES::
280
281
sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
282
sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
283
sage: f.__nonzero__()
284
True
285
sage: bool(f)
286
True
287
"""
288
return True
289
290
def _short_repr(self):
291
"""
292
EXAMPLES::
293
294
sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
295
sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
296
sage: f._short_repr()
297
'y |--> 2*y'
298
"""
299
a = '%s |--> %s'%(self.domain().gen(), self._im_gen)
300
if self._base_morphism is not None:
301
a += ', ' + self._base_morphism._short_repr()
302
return a
303
304
def _call_(self, x):
305
"""
306
EXAMPLES::
307
308
sage: R.<x> = FunctionField(GF(7)); S.<y> = R[]
309
sage: L.<y> = R.extension(y^3 + 6*x^3 + x); f = L.hom(y*2)
310
sage: f(y/x + x^2/(x+1)) # indirect doctest
311
2/x*y + x^2/(x + 1)
312
sage: f(y)
313
2*y
314
"""
315
v = x.list()
316
if self._base_morphism is not None:
317
v = [self._base_morphism(a) for a in v]
318
f = v[0].parent()['X'](v)
319
return f(self._im_gen)
320
321
class FunctionFieldMorphism_rational(FunctionFieldMorphism):
322
def __init__(self, parent, im_gen):
323
"""
324
EXAMPLES::
325
326
sage: R.<x> = FunctionField(GF(7)); f = R.hom(1/x); f
327
Morphism of function fields defined by x |--> 1/x
328
sage: type(f)
329
<class 'sage.rings.function_field.maps.FunctionFieldMorphism_rational'>
330
"""
331
Map.__init__(self, parent)
332
self._im_gen = im_gen
333
self._base_morphism = None
334
335
def _call_(self, x):
336
"""
337
EXAMPLES::
338
339
sage: R.<x> = FunctionField(GF(7)); f = R.hom(1/x); f
340
Morphism of function fields defined by x |--> 1/x
341
sage: f(x+1) # indirect doctest
342
(x + 1)/x
343
sage: 1/x + 1
344
(x + 1)/x
345
"""
346
a = x.element()
347
return a.subs({a.parent().gen():self._im_gen})
348
349