Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/rings/function_field/function_field.py
8820 views
1
"""
2
Function Fields
3
4
AUTHORS:
5
6
- William Stein (2010): initial version
7
8
- Robert Bradshaw (2010-05-30): added is_finite()
9
10
- Julian Rueth (2011-06-08): fixed hom(), extension()
11
12
- Maarten Derickx (2011-09-11): added doctests
13
14
- Julian Rueth (2011-09-14): use @cached_method
15
16
- Syed Ahmad Lavasani (2011-12-16): added genus(), is_RationalFunctionField()
17
18
EXAMPLES:
19
20
We create an extension of a rational function fields, and do some
21
simple arithmetic in it::
22
23
sage: K.<x> = FunctionField(GF(5^2,'a')); K
24
Rational function field in x over Finite Field in a of size 5^2
25
sage: R.<y> = K[]
26
sage: L.<y> = K.extension(y^3 - (x^3 + 2*x*y + 1/x)); L
27
Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x
28
sage: y^2
29
y^2
30
sage: y^3
31
2*x*y + (x^4 + 1)/x
32
sage: a = 1/y; a
33
(4*x/(4*x^4 + 4))*y^2 + 2*x^2/(4*x^4 + 4)
34
sage: a * y
35
1
36
37
We next make an extension of the above function field, illustrating
38
that arithmetic with a tower of 3 fields is fully supported::
39
40
sage: S.<t> = L[]
41
sage: M.<t> = L.extension(t^2 - x*y)
42
sage: M
43
Function field in t defined by t^2 + 4*x*y
44
sage: t^2
45
x*y
46
sage: 1/t
47
((1/(x^4 + 1))*y^2 + 2*x/(4*x^4 + 4))*t
48
sage: M.base_field()
49
Function field in y defined by y^3 + 3*x*y + (4*x^4 + 4)/x
50
sage: M.base_field().base_field()
51
Rational function field in x over Finite Field in a of size 5^2
52
53
TESTS::
54
55
sage: TestSuite(K).run()
56
sage: TestSuite(L).run() # long time (8s on sage.math, 2012)
57
sage: TestSuite(M).run() # long time (52s on sage.math, 2012)
58
59
The following two test suites do not pass ``_test_elements`` yet since
60
``R.an_element()`` has a ``_test_category`` method wich it should not have.
61
It is not the fault of the function field code so this will
62
be fixed in another ticket::
63
64
sage: TestSuite(R).run(skip = '_test_elements')
65
sage: TestSuite(S).run(skip = '_test_elements')
66
"""
67
#*****************************************************************************
68
# Copyright (C) 2010 William Stein <[email protected]>
69
# Copyright (C) 2010 Robert Bradshaw <[email protected]>
70
# Copyright (C) 2011 Julian Rueth <[email protected]>
71
# Copyright (C) 2011 Maarten Derickx <[email protected]>
72
#
73
# Distributed under the terms of the GNU General Public License (GPL)
74
# as published by the Free Software Foundation; either version 2 of
75
# the License, or (at your option) any later version.
76
# http://www.gnu.org/licenses/
77
#*****************************************************************************
78
79
from sage.rings.ring import Field
80
from function_field_element import FunctionFieldElement, FunctionFieldElement_rational, FunctionFieldElement_polymod
81
82
from sage.misc.cachefunc import cached_method
83
84
#is needed for genus computation
85
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
86
from sage.interfaces.all import singular
87
88
from sage.categories.function_fields import FunctionFields
89
CAT = FunctionFields()
90
91
def is_FunctionField(x):
92
"""
93
Return True if ``x`` is of function field type.
94
95
EXAMPLES::
96
97
sage: from sage.rings.function_field.function_field import is_FunctionField
98
sage: is_FunctionField(QQ)
99
False
100
sage: is_FunctionField(FunctionField(QQ,'t'))
101
True
102
"""
103
if isinstance(x, FunctionField): return True
104
return x in FunctionFields()
105
106
class FunctionField(Field):
107
"""
108
The abstract base class for all function fields.
109
110
EXAMPLES::
111
112
sage: K.<x> = FunctionField(QQ)
113
sage: isinstance(K, sage.rings.function_field.function_field.FunctionField)
114
True
115
"""
116
def some_elements(self):
117
"""
118
Return a list of elements in the function field.
119
120
EXAMPLES::
121
122
sage: K.<x> = FunctionField(QQ)
123
sage: elements = K.some_elements()
124
sage: elements # random output
125
[(x - 3/2)/(x^2 - 12/5*x + 1/18)]
126
sage: False in [e in K for e in elements]
127
False
128
"""
129
return [self.random_element(), self.random_element(), self.random_element()]
130
131
def characteristic(self):
132
"""
133
Return the characteristic of this function field.
134
135
EXAMPLES::
136
137
sage: K.<x> = FunctionField(QQ)
138
sage: K.characteristic()
139
0
140
sage: K.<x> = FunctionField(GF(7))
141
sage: K.characteristic()
142
7
143
sage: R.<y> = K[]
144
sage: L.<y> = K.extension(y^2-x)
145
sage: L.characteristic()
146
7
147
"""
148
return self.constant_base_field().characteristic()
149
150
def is_finite(self):
151
"""
152
Return whether this function field is finite, which it is not.
153
154
EXAMPLES::
155
156
sage: R.<t> = FunctionField(QQ)
157
sage: R.is_finite()
158
False
159
sage: R.<t> = FunctionField(GF(7))
160
sage: R.is_finite()
161
False
162
"""
163
return False
164
165
def extension(self, f, names=None):
166
"""
167
Create an extension L = K[y]/(f(y)) of a function field,
168
defined by a univariate polynomial in one variable over this
169
function field K.
170
171
INPUT:
172
173
- ``f`` -- a univariate polynomial over self
174
- ``names`` -- None or string or length-1 tuple
175
176
OUTPUT:
177
178
- a function field
179
180
EXAMPLES::
181
182
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
183
sage: K.extension(y^5 - x^3 - 3*x + x*y)
184
Function field in y defined by y^5 + x*y - x^3 - 3*x
185
186
A nonintegral defining polynomial::
187
188
sage: K.<t> = FunctionField(QQ); R.<y> = K[]
189
sage: K.extension(y^3 + (1/t)*y + t^3/(t+1))
190
Function field in y defined by y^3 + 1/t*y + t^3/(t + 1)
191
192
The defining polynomial need not be monic or integral::
193
194
sage: K.extension(t*y^3 + (1/t)*y + t^3/(t+1))
195
Function field in y defined by t*y^3 + 1/t*y + t^3/(t + 1)
196
"""
197
from constructor import FunctionField_polymod as FunctionField_polymod_Constructor
198
return FunctionField_polymod_Constructor(f, names)
199
200
def order_with_basis(self, basis, check=True):
201
"""
202
Return the order with given basis over the maximal order of
203
the base field.
204
205
INPUT:
206
207
- ``basis`` -- a list of elements of self
208
- ``check`` -- bool (default: True); if True, check that
209
the basis is really linearly independent and that the
210
module it spans is closed under multiplication, and
211
contains the identity element.
212
213
OUTPUT:
214
215
- an order in this function field
216
217
EXAMPLES::
218
219
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<y> = K.extension(y^3 + x^3 + 4*x + 1)
220
sage: O = L.order_with_basis([1, y, y^2]); O
221
Order in Function field in y defined by y^3 + x^3 + 4*x + 1
222
sage: O.basis()
223
(1, y, y^2)
224
225
Note that 1 does not need to be an element of the basis, as long it is in the module spanned by it::
226
227
sage: O = L.order_with_basis([1+y, y, y^2]); O
228
Order in Function field in y defined by y^3 + x^3 + 4*x + 1
229
sage: O.basis()
230
(y + 1, y, y^2)
231
232
The following error is raised when the module spanned by the basis is not closed under multiplication::
233
234
sage: O = L.order_with_basis([1, x^2 + x*y, (2/3)*y^2]); O
235
Traceback (most recent call last):
236
...
237
ValueError: The module generated by basis [1, x*y + x^2, 2/3*y^2] must be closed under multiplication
238
239
and this happens when the identity is not in the module spanned by the basis::
240
241
sage: O = L.order_with_basis([x, x^2 + x*y, (2/3)*y^2])
242
Traceback (most recent call last):
243
...
244
ValueError: The identity element must be in the module spanned by basis [x, x*y + x^2, 2/3*y^2]
245
"""
246
from function_field_order import FunctionFieldOrder_basis
247
return FunctionFieldOrder_basis([self(a) for a in basis], check=check)
248
249
def order(self, x, check=True):
250
"""
251
Return the order in this function field generated over the
252
maximal order by x or the elements of x if x is a list.
253
254
INPUT:
255
256
- ``x`` -- element of self, or a list of elements of self
257
- ``check`` -- bool (default: True); if True, check that
258
x really generates an order
259
260
EXAMPLES::
261
262
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<y> = K.extension(y^3 + x^3 + 4*x + 1)
263
sage: O = L.order(y); O
264
Order in Function field in y defined by y^3 + x^3 + 4*x + 1
265
sage: O.basis()
266
(1, y, y^2)
267
268
sage: Z = K.order(x); Z
269
Order in Rational function field in x over Rational Field
270
sage: Z.basis()
271
(1,)
272
273
Orders with multiple generators, not yet supported::
274
275
sage: Z = K.order([x,x^2]); Z
276
Traceback (most recent call last):
277
...
278
NotImplementedError
279
"""
280
if not isinstance(x, (list, tuple)):
281
x = [x]
282
if len(x) == 1:
283
g = x[0]
284
basis = [self(1)]
285
for i in range(self.degree()-1):
286
basis.append(basis[-1]*g)
287
else:
288
raise NotImplementedError
289
return self.order_with_basis(basis, check=check)
290
291
def _coerce_map_from_(self, R):
292
"""
293
Return True if there is a coerce map from R to self.
294
295
EXAMPLES::
296
297
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<y> = K.extension(y^3 + x^3 + 4*x + 1)
298
sage: L.equation_order()
299
Order in Function field in y defined by y^3 + x^3 + 4*x + 1
300
sage: L._coerce_map_from_(L.equation_order())
301
True
302
sage: L._coerce_map_from_(GF(7))
303
False
304
"""
305
from function_field_order import FunctionFieldOrder
306
if isinstance(R, FunctionFieldOrder) and R.fraction_field() == self:
307
return True
308
return False
309
310
class FunctionField_polymod(FunctionField):
311
"""
312
A function field defined by a univariate polynomial, as an
313
extension of the base field.
314
315
EXAMPLES:
316
317
We make a function field defined by a degree 5 polynomial over the
318
rational function field over the rational numbers::
319
320
sage: K.<x> = FunctionField(QQ)
321
sage: R.<y> = K[]
322
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
323
Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
324
325
We next make a function field over the above nontrivial function
326
field L::
327
328
sage: S.<z> = L[]
329
sage: M.<z> = L.extension(z^2 + y*z + y); M
330
Function field in z defined by z^2 + y*z + y
331
sage: 1/z
332
((x/(-x^4 - 1))*y^4 - 2*x^2/(-x^4 - 1))*z - 1
333
sage: z * (1/z)
334
1
335
336
We drill down the tower of function fields::
337
338
sage: M.base_field()
339
Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
340
sage: M.base_field().base_field()
341
Rational function field in x over Rational Field
342
sage: M.base_field().base_field().constant_field()
343
Rational Field
344
sage: M.constant_base_field()
345
Rational Field
346
347
.. WARNING::
348
349
It is not checked if the polynomial used to define this function field is irreducible
350
Hence it is not guaranteed that this object really is a field!
351
This is illustrated below.
352
353
::
354
355
sage: K.<x>=FunctionField(QQ)
356
sage: R.<y> = K[]
357
sage: L.<y>=K.extension(x^2-y^2)
358
sage: (y-x)*(y+x)
359
0
360
sage: 1/(y-x)
361
1
362
sage: y-x==0; y+x==0
363
False
364
False
365
"""
366
def __init__(self, polynomial, names,
367
element_class = FunctionFieldElement_polymod,
368
category=CAT):
369
"""
370
Create a function field defined as an extension of another
371
function field by adjoining a root of a univariate polynomial.
372
373
INPUT:
374
375
- ``polynomial`` -- a univariate polynomial over a function field
376
- ``names`` -- variable names (as a tuple of length 1 or string)
377
- ``category`` -- a category (defaults to category of function fields)
378
379
EXAMPLES::
380
381
We create an extension of a function field::
382
383
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
384
sage: L = K.extension(y^5 - x^3 - 3*x + x*y); L
385
Function field in y defined by y^5 + x*y - x^3 - 3*x
386
387
Note the type::
388
389
sage: type(L)
390
<class 'sage.rings.function_field.function_field.FunctionField_polymod_with_category'>
391
392
We can set the variable name, which doesn't have to be y::
393
394
sage: L.<w> = K.extension(y^5 - x^3 - 3*x + x*y); L
395
Function field in w defined by y^5 + x*y - x^3 - 3*x
396
"""
397
from sage.rings.polynomial.all import is_Polynomial
398
if polynomial.parent().ngens()>1 or not is_Polynomial(polynomial):
399
raise TypeError, "polynomial must be univariate a polynomial"
400
if names is None:
401
names = (polynomial.variable_name(), )
402
if polynomial.degree() <= 0:
403
raise ValueError, "polynomial must have positive degree"
404
base_field = polynomial.base_ring()
405
if not isinstance(base_field, FunctionField):
406
raise TypeError, "polynomial must be over a FunctionField"
407
self._element_class = element_class
408
self._element_init_pass_parent = False
409
self._base_field = base_field
410
self._polynomial = polynomial
411
412
Field.__init__(self, base_field,
413
names=names, category = category)
414
415
self._hash = hash(polynomial)
416
self._ring = self._polynomial.parent()
417
self._populate_coercion_lists_(coerce_list=[base_field, self._ring])
418
self._gen = self(self._ring.gen())
419
420
def __reduce__(self):
421
"""
422
Returns the arguments which were used to create this instance. The rationale for this is explained in the documentation of ``UniqueRepresentation``.
423
424
EXAMPLES::
425
426
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
427
sage: L = K.extension(y^2-x)
428
sage: clazz,args = L.__reduce__()
429
sage: clazz(*args)
430
Function field in y defined by y^2 - x
431
"""
432
from constructor import FunctionField_polymod as FunctionField_polymod_Constructor
433
return FunctionField_polymod_Constructor, (self._polynomial, self._names)
434
435
def __hash__(self):
436
"""
437
Return hash of this function field.
438
439
EXAMPLES::
440
441
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
442
sage: L = K.extension(y^5 - x^3 - 3*x + x*y); hash(L)
443
3183366741743088279 # 64-bit
444
2003022487 # 32-bit
445
"""
446
return self._hash
447
448
def monic_integral_model(self, names):
449
"""
450
Return a function field isomorphic to self, but with defining
451
polynomial that is monic and integral over the base field.
452
453
INPUT:
454
455
- ``names`` -- name of the generator of the new field this function constructs
456
457
EXAMPLES::
458
459
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
460
sage: L.<y> = K.extension(x^2*y^5 - 1/x); L
461
Function field in y defined by x^2*y^5 - 1/x
462
sage: A, from_A, to_A = L.monic_integral_model('z')
463
sage: A
464
Function field in z defined by y^5 - x^12
465
sage: from_A
466
Morphism of function fields defined by z |--> x^3*y
467
sage: to_A
468
Morphism of function fields defined by y |--> 1/x^3*z
469
sage: to_A(y)
470
1/x^3*z
471
sage: from_A(to_A(y))
472
y
473
sage: from_A(to_A(1/y))
474
x^3*y^4
475
sage: from_A(to_A(1/y)) == 1/y
476
True
477
"""
478
g, d = self._make_monic_integral(self.polynomial())
479
R = self.base_field()
480
K = R.extension(g, names=names)
481
to_K = self.hom(K.gen() / d)
482
from_K = K.hom(self.gen() * d)
483
return K, from_K, to_K
484
485
def _make_monic_integral(self, f):
486
r"""
487
Let y be a root of ``f``. This function returns a monic
488
integral polynomial g and an element d of the base field such
489
that g(y*d)=0.
490
491
EXAMPLES::
492
493
sage: K.<x> = FunctionField(QQ); R.<y> = K[];
494
sage: L.<y> = K.extension(x^2*y^5 - 1/x)
495
sage: g, d = L._make_monic_integral(L.polynomial()); g,d
496
(y^5 - x^12, x^3)
497
sage: (y*d).is_integral()
498
True
499
sage: g.is_monic()
500
True
501
sage: g(y*d)
502
0
503
"""
504
R = f.base_ring()
505
if not isinstance(R, RationalFunctionField):
506
raise NotImplementedError
507
508
# make f monic
509
n = f.degree()
510
c = f.leading_coefficient()
511
if c != 1:
512
f = f / c
513
514
# find lcm of denominators
515
from sage.rings.arith import lcm
516
# would be good to replace this by minimal...
517
d = lcm([b.denominator() for b in f.list() if b])
518
if d != 1:
519
x = f.parent().gen()
520
g = (d**n) * f(x/d)
521
else:
522
g = f
523
return g, d
524
525
def constant_field(self):
526
"""
527
Return the algebraic closure of the constant field of the base
528
field in this function field.
529
530
EXAMPLES::
531
532
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
533
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
534
sage: L.constant_field()
535
Traceback (most recent call last):
536
...
537
NotImplementedError
538
"""
539
raise NotImplementedError
540
541
def constant_base_field(self):
542
"""
543
Return the constant field of the base rational function field.
544
545
EXAMPLES::
546
547
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
548
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
549
Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
550
sage: L.constant_base_field()
551
Rational Field
552
sage: S.<z> = L[]
553
sage: M.<z> = L.extension(z^2 - y)
554
sage: M.constant_base_field()
555
Rational Field
556
"""
557
return self.base_field().constant_base_field()
558
559
def degree(self):
560
"""
561
Return the degree of this function field over its base
562
function field.
563
564
EXAMPLES::
565
566
sage: K.<x> = FunctionField(QQ)
567
sage: R.<y> = K[]
568
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
569
Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
570
sage: L.degree()
571
5
572
"""
573
return self._polynomial.degree()
574
575
def _repr_(self):
576
"""
577
Return string representation of this function field.
578
579
EXAMPLES::
580
581
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
582
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
583
sage: L._repr_()
584
'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x'
585
"""
586
return "Function field in %s defined by %s"%(self.variable_name(), self._polynomial)
587
588
def base_field(self):
589
"""
590
Return the base field of this function field. This function
591
field is presented as L = K[y]/(f(y)), and the base field is
592
by definition the field K.
593
594
EXAMPLES::
595
596
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
597
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
598
sage: L.base_field()
599
Rational function field in x over Rational Field
600
"""
601
return self._base_field
602
603
def random_element(self, *args, **kwds):
604
"""
605
Create a random element of this function field. Parameters
606
are passed onto the random_element method of the base_field.
607
608
EXAMPLES::
609
610
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
611
sage: L.<y> = K.extension(y^2 - (x^2 + x))
612
sage: L.random_element() # random
613
((x^2 - x + 2/3)/(x^2 + 1/3*x - 1))*y^2 + ((-1/4*x^2 + 1/2*x - 1)/(-5/2*x + 2/3))*y + (-1/2*x^2 - 4)/(-12*x^2 + 1/2*x - 1/95)
614
"""
615
return self(self._ring.random_element(degree=self.degree(), *args, **kwds))
616
617
def polynomial(self):
618
"""
619
Return the univariate polynomial that defines this function
620
field, i.e., the polynomial f(y) so that this function field
621
is of the form K[y]/(f(y)).
622
623
EXAMPLES::
624
625
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
626
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
627
sage: L.polynomial()
628
y^5 - 2*x*y + (-x^4 - 1)/x
629
"""
630
return self._polynomial
631
632
def polynomial_ring(self):
633
"""
634
Return the polynomial ring used to represent elements of this
635
function field. If we view this function field as being presented
636
as K[y]/(f(y)), then this function returns the ring K[y].
637
638
EXAMPLES::
639
640
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
641
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
642
sage: L.polynomial_ring()
643
Univariate Polynomial Ring in y over Rational function field in x over Rational Field
644
"""
645
return self._ring
646
647
@cached_method
648
def vector_space(self):
649
"""
650
Return a vector space V and isomorphisms self --> V and V --> self.
651
652
This function allows us to identify the elements of self with
653
elements of a vector space over the base field, which is
654
useful for representation and arithmetic with orders, ideals,
655
etc.
656
657
OUTPUT:
658
659
- ``V`` -- a vector space over base field
660
- ``from_V`` -- an isomorphism from V to self
661
- ``to_V`` -- an isomorphism from self to V
662
663
EXAMPLES:
664
665
We define a function field::
666
667
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
668
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x)); L
669
Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
670
671
We get the vector spaces, and maps back and forth::
672
673
sage: V, from_V, to_V = L.vector_space()
674
sage: V
675
Vector space of dimension 5 over Rational function field in x over Rational Field
676
sage: from_V
677
Isomorphism morphism:
678
From: Vector space of dimension 5 over Rational function field in x over Rational Field
679
To: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
680
sage: to_V
681
Isomorphism morphism:
682
From: Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
683
To: Vector space of dimension 5 over Rational function field in x over Rational Field
684
685
We convert an element of the vector space back to the function field::
686
687
sage: from_V(V.1)
688
y
689
690
We define an interesting element of the function field::
691
692
sage: a = 1/L.0; a
693
(-x/(-x^4 - 1))*y^4 + 2*x^2/(-x^4 - 1)
694
695
We convert it to the vector space, and get a vector over the base field::
696
697
sage: to_V(a)
698
(2*x^2/(-x^4 - 1), 0, 0, 0, -x/(-x^4 - 1))
699
700
We convert to and back, and get the same element::
701
702
sage: from_V(to_V(a)) == a
703
True
704
705
In the other direction::
706
707
sage: v = x*V.0 + (1/x)*V.1
708
sage: to_V(from_V(v)) == v
709
True
710
711
And we show how it works over an extension of an extension field::
712
713
sage: R2.<z> = L[]; M.<z> = L.extension(z^2 -y)
714
sage: M.vector_space()
715
(Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x, Isomorphism morphism:
716
From: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x
717
To: Function field in z defined by z^2 - y, Isomorphism morphism:
718
From: Function field in z defined by z^2 - y
719
To: Vector space of dimension 2 over Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x)
720
"""
721
V = self.base_field()**self.degree()
722
from maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace
723
from_V = MapVectorSpaceToFunctionField(V, self)
724
to_V = MapFunctionFieldToVectorSpace(self, V)
725
return (V, from_V, to_V)
726
727
def maximal_order(self):
728
"""
729
Return the maximal_order of self. If we view self as L =
730
K[y]/(f(y)), then this is the ring of elements of L that are
731
integral over K.
732
733
EXAMPLES:
734
735
This is not yet implemented...::
736
737
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
738
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
739
sage: L.maximal_order()
740
Traceback (most recent call last):
741
...
742
NotImplementedError
743
"""
744
raise NotImplementedError
745
746
def _element_constructor_(self, x):
747
r"""
748
Make ``x`` into an element of this function field, possibly not canonically.
749
750
INPUT:
751
752
- ``x`` -- the element
753
754
OUTPUT:
755
756
``x``, as an element of this function field
757
758
TESTS::
759
760
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
761
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
762
sage: L._element_constructor_(L.polynomial_ring().gen())
763
y
764
"""
765
if x.parent() is self._ring:
766
return FunctionFieldElement_polymod(self, x)
767
if isinstance(x, FunctionFieldElement):
768
return FunctionFieldElement_polymod(self, self._ring(x.element()))
769
return FunctionFieldElement_polymod(self, self._ring(x))
770
771
def gen(self, n=0):
772
"""
773
Return the ``n``-th generator of this function field. By default ``n`` is 0; any other
774
value of ``n`` leads to an error. The generator is the class of y, if we view
775
self as being presented as K[y]/(f(y)).
776
777
EXAMPLES::
778
779
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
780
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
781
sage: L.gen()
782
y
783
sage: L.gen(1)
784
Traceback (most recent call last):
785
...
786
IndexError: Only one generator.
787
"""
788
if n != 0: raise IndexError, "Only one generator."
789
return self._gen
790
791
def ngens(self):
792
"""
793
Return the number of generators of this function field over
794
its base field. This is by definition 1.
795
796
EXAMPLES::
797
798
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
799
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
800
sage: L.ngens()
801
1
802
"""
803
return 1
804
805
def equation_order(self):
806
"""
807
If we view self as being presented as K[y]/(f(y)), then this
808
function returns the order generated by the class of y. If f
809
is not monic, then :meth:`_make_monic_integral` is called, and instead we
810
get the order generated by some integral multiple of a root of f.
811
812
EXAMPLES::
813
814
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
815
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
816
sage: O = L.equation_order()
817
sage: O.basis()
818
(1, x*y, x^2*y^2, x^3*y^3, x^4*y^4)
819
820
We try an example, in which the defining polynomial is not
821
monic and is not integral::
822
823
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
824
sage: L.<y> = K.extension(x^2*y^5 - 1/x); L
825
Function field in y defined by x^2*y^5 - 1/x
826
sage: O = L.equation_order()
827
sage: O.basis()
828
(1, x^3*y, x^6*y^2, x^9*y^3, x^12*y^4)
829
"""
830
d = self._make_monic_integral(self.polynomial())[1]
831
return self.order(d*self.gen(), check=False)
832
833
def hom(self, im_gens, base_morphism=None):
834
"""
835
Create a homomorphism from self to another function field.
836
837
INPUT:
838
839
- ``im_gens`` -- a list of images of the generators of self
840
and of successive base rings.
841
842
- ``base_morphism`` -- (default: None) a homomorphism of
843
the base ring, after the im_gens are used. Thus if
844
im_gens has length 2, then base_morphism should be a morphism
845
from self.base_ring().base_ring().
846
847
EXAMPLES:
848
849
We create a rational function field, and a quadratic extension of it::
850
851
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
852
sage: L.<y> = K.extension(y^2 - x^3 - 1)
853
854
We make the field automorphism that sends y to -y::
855
856
sage: f = L.hom(-y); f
857
Morphism of function fields defined by y |--> -y
858
859
Evaluation works::
860
861
sage: f(y*x - 1/x)
862
-x*y - 1/x
863
864
We try to define an invalid morphism::
865
866
sage: f = L.hom(y+1)
867
Traceback (most recent call last):
868
...
869
ValueError: invalid morphism
870
871
We make a morphism of the base rational function field::
872
873
sage: phi = K.hom(x+1); phi
874
Morphism of function fields defined by x |--> x + 1
875
sage: phi(x^3 - 3)
876
x^3 + 3*x^2 + 3*x - 2
877
sage: (x+1)^3-3
878
x^3 + 3*x^2 + 3*x - 2
879
880
We make a morphism by specifying where the generators and the
881
base generators go::
882
883
sage: L.hom([-y, x])
884
Morphism of function fields defined by y |--> -y, x |--> x
885
886
The usage of the keyword base_morphism is not implemented yet::
887
888
sage: L.hom([-y, x-1], base_morphism=phi)
889
Traceback (most recent call last):
890
...
891
NotImplementedError: Function field homorphisms with optional argument base_morphism are not implemented yet. Please specify the images of the generators of the base fields manually.
892
893
We make another extension of a rational function field::
894
895
sage: K2.<t> = FunctionField(QQ); R2.<w> = K2[]
896
sage: L2.<w> = K2.extension((4*w)^2 - (t+1)^3 - 1)
897
898
We define a morphism, by giving the images of generators::
899
900
sage: f = L.hom([4*w, t+1]); f
901
Morphism of function fields defined by y |--> 4*w, x |--> t + 1
902
903
Evaluation works, as expected::
904
905
sage: f(y+x)
906
4*w + t + 1
907
sage: f(x*y + x/(x^2+1))
908
(4*t + 4)*w + (t + 1)/(t^2 + 2*t + 2)
909
910
We make another extension of a rational function field::
911
912
sage: K3.<yy> = FunctionField(QQ); R3.<xx> = K3[]
913
sage: L3.<xx> = K3.extension(yy^2 - xx^3 - 1)
914
915
This is the function field L with the generators exchanged. We define a morphism to L::
916
917
sage: g = L3.hom([x,y]); g
918
Morphism of function fields defined by xx |--> x, yy |--> y
919
"""
920
if base_morphism is not None:
921
raise NotImplementedError, "Function field homorphisms with optional argument base_morphism are not implemented yet. Please specify the images of the generators of the base fields manually."
922
923
if not isinstance(im_gens, (list,tuple)):
924
im_gens = [im_gens]
925
if len(im_gens) == 0:
926
raise ValueError, "no images specified"
927
928
if len(im_gens) > 1:
929
base_morphism = self.base_field().hom(im_gens[1:], base_morphism)
930
931
# the codomain of this morphism is the field containing all the im_gens
932
codomain = im_gens[0].parent();
933
if base_morphism is not None:
934
if base_morphism.codomain().has_coerce_map_from(codomain):
935
codomain = base_morphism.codomain();
936
937
from maps import FunctionFieldMorphism_polymod
938
return FunctionFieldMorphism_polymod(self.Hom(codomain), im_gens[0], base_morphism)
939
940
@cached_method
941
def genus(self):
942
"""
943
Return the genus of this function field
944
For now, the genus is computed using singular
945
946
EXAMPLES::
947
948
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
949
sage: L.<y> = K.extension(y^3 - (x^3 + 2*x*y + 1/x))
950
sage: L.genus()
951
3
952
"""
953
# unfortunately singular can not compute the genus with the polynomial_ring()._singular_
954
# object because genus method only accepts a ring of transdental degree 2 over a prime field
955
# not a ring of transdental degree 1 over a rational function field of one variable
956
957
if is_RationalFunctionField(self._base_field) and self._base_field.constant_field().is_prime_field():
958
959
#Making the auxiliary ring which only has polynomials with integral coefficients.
960
tmpAuxRing = PolynomialRing(self._base_field.constant_field(), str(self._base_field.gen())+','+str(self._ring.gen()))
961
intMinPoly, d = self._make_monic_integral(self._polynomial)
962
curveIdeal = tmpAuxRing.ideal(intMinPoly)
963
964
singular.lib('normal.lib') #loading genus method in singular
965
return int(curveIdeal._singular_().genus())
966
967
else:
968
raise NotImplementedError, "Computation of genus over this rational function field not implemented yet"
969
970
def is_RationalFunctionField(x):
971
"""
972
Return True if ``x`` is of rational function field type.
973
974
EXAMPLES::
975
976
sage: from sage.rings.function_field.function_field import is_RationalFunctionField
977
sage: is_RationalFunctionField(QQ)
978
False
979
sage: is_RationalFunctionField(FunctionField(QQ,'t'))
980
True
981
"""
982
if isinstance(x, RationalFunctionField):
983
return True
984
# if (x in FunctionFields()):
985
# return x == x.base_field()
986
else:
987
return False
988
989
class RationalFunctionField(FunctionField):
990
"""
991
A rational function field K(t) in one variable, over an arbitrary
992
base field.
993
994
EXAMPLES::
995
996
sage: K.<t> = FunctionField(GF(3)); K
997
Rational function field in t over Finite Field of size 3
998
sage: K.gen()
999
t
1000
sage: 1/t + t^3 + 5
1001
(t^4 + 2*t + 1)/t
1002
1003
There are various ways to get at the underlying fields and rings
1004
associated to a rational function field::
1005
1006
sage: K.<t> = FunctionField(GF(7))
1007
sage: K.base_field()
1008
Rational function field in t over Finite Field of size 7
1009
sage: K.field()
1010
Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
1011
sage: K.constant_field()
1012
Finite Field of size 7
1013
sage: K.maximal_order()
1014
Maximal order in Rational function field in t over Finite Field of size 7
1015
1016
We define a morphism::
1017
1018
sage: K.<t> = FunctionField(QQ)
1019
sage: L = FunctionField(QQ, 'tbar') # give variable name as second input
1020
sage: K.hom(L.gen())
1021
Morphism of function fields defined by t |--> tbar
1022
"""
1023
def __init__(self, constant_field, names,
1024
element_class = FunctionFieldElement_rational,
1025
category=CAT):
1026
"""
1027
Create a rational function field in one variable.
1028
1029
INPUT:
1030
1031
- ``constant_field`` -- an arbitrary field
1032
- ``names`` -- a string or tuple of length 1
1033
- ``category`` -- default: FunctionFields()
1034
1035
EXAMPLES::
1036
1037
sage: K.<t> = FunctionField(CC); K
1038
Rational function field in t over Complex Field with 53 bits of precision
1039
sage: K.category()
1040
Category of function fields
1041
sage: FunctionField(QQ[I], 'alpha')
1042
Rational function field in alpha over Number Field in I with defining polynomial x^2 + 1
1043
1044
Must be over a field::
1045
1046
sage: FunctionField(ZZ, 't')
1047
Traceback (most recent call last):
1048
...
1049
TypeError: constant_field must be a field
1050
"""
1051
if names is None:
1052
raise ValueError, "variable name must be specified"
1053
elif not isinstance(names, tuple):
1054
names = (names, )
1055
if not constant_field.is_field():
1056
raise TypeError, "constant_field must be a field"
1057
self._element_class = element_class
1058
self._element_init_pass_parent = False
1059
Field.__init__(self, self, names=names, category = category)
1060
R = constant_field[names[0]]
1061
self._hash = hash((constant_field, names))
1062
self._constant_field = constant_field
1063
self._ring = R
1064
self._field = R.fraction_field()
1065
self._populate_coercion_lists_(coerce_list=[self._field])
1066
self._gen = self(R.gen())
1067
1068
def __reduce__(self):
1069
"""
1070
Returns the arguments which were used to create this instance. The rationale for this is explained in the documentation of ``UniqueRepresentation``.
1071
1072
EXAMPLES::
1073
1074
sage: K.<x> = FunctionField(QQ)
1075
sage: clazz,args = K.__reduce__()
1076
sage: clazz(*args)
1077
Rational function field in x over Rational Field
1078
"""
1079
from constructor import FunctionField
1080
return FunctionField, (self._constant_field, self._names)
1081
1082
def __hash__(self):
1083
"""
1084
Return hash of this function field.
1085
1086
EXAMPLES::
1087
1088
sage: K.<t> = FunctionField(QQ)
1089
sage: hash(K)
1090
502145503910697533 # 64-bit
1091
-500688323 # 32-bit
1092
"""
1093
return self._hash
1094
1095
def _repr_(self):
1096
"""
1097
Return string representation of this function field.
1098
1099
EXAMPLES::
1100
1101
sage: K.<t> = FunctionField(QQ)
1102
sage: K._repr_()
1103
'Rational function field in t over Rational Field'
1104
"""
1105
return "Rational function field in %s over %s"%(
1106
self.variable_name(), self._constant_field)
1107
1108
def _element_constructor_(self, x):
1109
r"""
1110
Coerce ``x`` into an element of this function field, possibly not canonically.
1111
1112
INPUT:
1113
1114
- ``x`` -- the element
1115
1116
OUTPUT:
1117
1118
``x``, as an element of this function field
1119
1120
EXAMPLES::
1121
1122
sage: K.<t> = FunctionField(QQ)
1123
sage: a = K._element_constructor_(K.maximal_order().gen()); a
1124
t
1125
sage: a.parent()
1126
Rational function field in t over Rational Field
1127
1128
"""
1129
if x.parent() is self._field:
1130
return FunctionFieldElement_rational(self, x)
1131
if isinstance(x, FunctionFieldElement):
1132
return FunctionFieldElement_rational(self, self._field(x.element()))
1133
if x.parent() is self.polynomial_ring():
1134
return x[0]
1135
return FunctionFieldElement_rational(self, self._field(x))
1136
1137
def _to_bivariate_polynomial(self, f):
1138
"""
1139
Convert ``f`` from a univariate polynomial over the rational function
1140
field into a bivariate polynomial and a denominator.
1141
1142
INPUT:
1143
1144
- ``f`` -- a univariate polynomial over self.
1145
1146
OUTPUT:
1147
1148
- bivariate polynomial, denominator
1149
1150
EXAMPLES::
1151
1152
sage: R.<t> = FunctionField(GF(7))
1153
sage: S.<X> = R[]
1154
sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
1155
sage: R._to_bivariate_polynomial(f)
1156
(X^7*t^2 - X^4*t^5 - X^3 + t^3, t^3)
1157
"""
1158
v = f.list()
1159
from sage.rings.arith import LCM
1160
denom = LCM([a.denominator() for a in v])
1161
S = denom.parent()
1162
x,t = S.base_ring()['%s,%s'%(f.parent().variable_name(),self.variable_name())].gens()
1163
phi = S.hom([t])
1164
return sum([phi((denom * v[i]).numerator()) * x**i for i in range(len(v))]), denom
1165
1166
def _factor_univariate_polynomial(self, f, proof=True):
1167
"""
1168
Factor the univariate polynomial ``f`` over self.
1169
1170
EXAMPLES::
1171
1172
We do a factorization over the function field over the rationals::
1173
1174
sage: R.<t> = FunctionField(QQ)
1175
sage: S.<X> = R[]
1176
sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
1177
sage: f.factor() # indirect doctest
1178
(1/t) * (X - t) * (X^2 - 1/t) * (X^2 + 1/t) * (X^2 + t*X + t^2)
1179
sage: f.factor().prod() == f
1180
True
1181
1182
We do a factorization over a finite prime field::
1183
1184
sage: R.<t> = FunctionField(GF(7))
1185
sage: S.<X> = R[]
1186
sage: f = (1/t)*(X^4 - 1/t^2)*(X^3 - t^3)
1187
sage: f.factor()
1188
(1/t) * (X + 3*t) * (X + 5*t) * (X + 6*t) * (X^2 + 1/t) * (X^2 + 6/t)
1189
sage: f.factor().prod() == f
1190
True
1191
1192
Factoring over a function field over a non-prime finite field::
1193
1194
sage: k.<a> = GF(9)
1195
sage: R.<t> = FunctionField(k)
1196
sage: S.<X> = R[]
1197
sage: f = (1/t)*(X^3 - a*t^3)
1198
sage: f.factor()
1199
(1/t) * (X + (a + 2)*t)^3
1200
sage: f.factor().prod() == f
1201
True
1202
"""
1203
F, d = self._to_bivariate_polynomial(f)
1204
fac = F.factor()
1205
x = f.parent().gen()
1206
t = f.parent().base_ring().gen()
1207
phi = F.parent().hom([x, t])
1208
v = [(phi(P),e) for P, e in fac]
1209
unit = phi(fac.unit())/d
1210
w = []
1211
for a, e in v:
1212
c = a.leading_coefficient()
1213
a = a/c
1214
unit *= (c**e)
1215
w.append((a,e))
1216
from sage.structure.factorization import Factorization
1217
return Factorization(w, unit=unit)
1218
1219
@cached_method
1220
def polynomial_ring(self, var='x'):
1221
"""
1222
Return a polynomial ring in one variable over this rational function field.
1223
1224
INPUT:
1225
1226
- ``var`` -- a string (default: 'x')
1227
1228
EXAMPLES::
1229
1230
sage: K.<x> = FunctionField(QQ)
1231
sage: K.polynomial_ring()
1232
Univariate Polynomial Ring in x over Rational function field in x over Rational Field
1233
sage: K.polynomial_ring('T')
1234
Univariate Polynomial Ring in T over Rational function field in x over Rational Field
1235
"""
1236
return self[var]
1237
1238
@cached_method
1239
def vector_space(self):
1240
"""
1241
Return a vector space V and isomorphisms self --> V and V --> self.
1242
1243
OUTPUT:
1244
1245
- ``V`` -- a vector space over the rational numbers
1246
- ``from_V`` -- an isomorphism from V to self
1247
- ``to_V`` -- an isomorphism from self to V
1248
1249
EXAMPLES::
1250
1251
sage: K.<x> = FunctionField(QQ)
1252
sage: K.vector_space()
1253
(Vector space of dimension 1 over Rational function field in x over Rational Field, Isomorphism morphism:
1254
From: Vector space of dimension 1 over Rational function field in x over Rational Field
1255
To: Rational function field in x over Rational Field, Isomorphism morphism:
1256
From: Rational function field in x over Rational Field
1257
To: Vector space of dimension 1 over Rational function field in x over Rational Field)
1258
"""
1259
V = self.base_field()**1
1260
from maps import MapVectorSpaceToFunctionField, MapFunctionFieldToVectorSpace
1261
from_V = MapVectorSpaceToFunctionField(V, self)
1262
to_V = MapFunctionFieldToVectorSpace(self, V)
1263
return (V, from_V, to_V)
1264
1265
def random_element(self, *args, **kwds):
1266
"""
1267
Create a random element of this rational function field.
1268
Parameters are passed onto the random_element method of the
1269
underlying fraction field.
1270
1271
EXAMPLES::
1272
1273
sage: FunctionField(QQ,'alpha').random_element()
1274
(-1/2*alpha^2 - 4)/(-12*alpha^2 + 1/2*alpha - 1/95)
1275
"""
1276
return self(self._field.random_element(*args, **kwds))
1277
1278
def degree(self):
1279
"""
1280
Return the degree over the base field of this rational
1281
function field. Since the base field is the rational function
1282
field itself, the degree is 1.
1283
1284
EXAMPLES::
1285
1286
sage: K.<t> = FunctionField(QQ)
1287
sage: K.degree()
1288
1
1289
"""
1290
from sage.rings.integer_ring import ZZ
1291
return ZZ(1)
1292
1293
def gen(self, n=0):
1294
"""
1295
Return the ``n``-th generator of this function field. If ``n`` is not
1296
0, then an IndexError is raised.
1297
1298
EXAMPLES::
1299
1300
sage: K.<t> = FunctionField(QQ); K.gen()
1301
t
1302
sage: K.gen().parent()
1303
Rational function field in t over Rational Field
1304
sage: K.gen(1)
1305
Traceback (most recent call last):
1306
...
1307
IndexError: Only one generator.
1308
"""
1309
if n != 0:
1310
raise IndexError, "Only one generator."
1311
return self._gen
1312
1313
def ngens(self):
1314
"""
1315
Return the number of generators, which is 1.
1316
1317
EXAMPLES::
1318
1319
sage: K.<t> = FunctionField(QQ)
1320
sage: K.ngens()
1321
1
1322
"""
1323
return 1
1324
1325
def base_field(self):
1326
"""
1327
Return the base field of this rational function field, which is just
1328
this function field itself.
1329
1330
EXAMPLES::
1331
1332
sage: K.<t> = FunctionField(GF(7))
1333
sage: K.base_field()
1334
Rational function field in t over Finite Field of size 7
1335
"""
1336
return self
1337
1338
def hom(self, im_gens, base_morphism=None):
1339
"""
1340
Create a homomorphism from self to another function field.
1341
1342
INPUT:
1343
1344
- ``im_gens`` -- exactly one element of some function field
1345
- ``base_morphism`` -- ignored
1346
1347
OUTPUT:
1348
1349
- a map between function fields
1350
1351
EXAMPLES:
1352
1353
We make a map from a rational function field to itself::
1354
1355
sage: K.<x> = FunctionField(GF(7))
1356
sage: K.hom( (x^4 + 2)/x)
1357
Morphism of function fields defined by x |--> (x^4 + 2)/x
1358
1359
We construct a map from a rational function field into a
1360
non-rational extension field::
1361
1362
sage: K.<x> = FunctionField(GF(7)); R.<y> = K[]
1363
sage: L.<y> = K.extension(y^3 + 6*x^3 + x)
1364
sage: f = K.hom(y^2 + y + 2); f
1365
Morphism of function fields defined by x |--> y^2 + y + 2
1366
sage: f(x)
1367
y^2 + y + 2
1368
sage: f(x^2)
1369
5*y^2 + (x^3 + 6*x + 4)*y + 2*x^3 + 5*x + 4
1370
"""
1371
from sage.structure.category_object import CategoryObject
1372
if isinstance(im_gens, CategoryObject):
1373
return self.Hom(im_gens).natural_map()
1374
if not isinstance(im_gens, (list,tuple)):
1375
im_gens = [im_gens]
1376
if len(im_gens) != 1:
1377
raise ValueError, "there must be exactly one generator"
1378
x = im_gens[0]
1379
from maps import FunctionFieldMorphism_rational
1380
return FunctionFieldMorphism_rational(self.Hom(x.parent()), x)
1381
1382
def field(self):
1383
"""
1384
Return the underlying field, forgetting the function field
1385
structure.
1386
1387
EXAMPLES::
1388
1389
sage: K.<t> = FunctionField(GF(7))
1390
sage: K.field()
1391
Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
1392
"""
1393
return self._field
1394
1395
@cached_method
1396
def maximal_order(self):
1397
"""
1398
Return the maximal order of this function field. Since this
1399
is a rational function field it is of the form K(t), and the
1400
maximal order is by definition K[t].
1401
1402
EXAMPLES::
1403
1404
sage: K.<t> = FunctionField(QQ)
1405
sage: K.maximal_order()
1406
Maximal order in Rational function field in t over Rational Field
1407
sage: K.equation_order()
1408
Maximal order in Rational function field in t over Rational Field
1409
"""
1410
from function_field_order import FunctionFieldOrder_rational
1411
return FunctionFieldOrder_rational(self)
1412
1413
equation_order = maximal_order
1414
1415
def constant_base_field(self):
1416
"""
1417
Return the field that this rational function field is a
1418
transcendental extension of.
1419
1420
EXAMPLES::
1421
1422
sage: K.<t> = FunctionField(QQ)
1423
sage: K.constant_field()
1424
Rational Field
1425
1426
"""
1427
return self._constant_field
1428
1429
constant_field = constant_base_field
1430
1431
def genus(self):
1432
"""
1433
Return the genus of this function field
1434
This is always equal 0 for a rational function field
1435
1436
EXAMPLES::
1437
1438
sage: K.<x> = FunctionField(QQ);
1439
sage: K.genus()
1440
0
1441
"""
1442
return 0
1443
1444
1445