Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/rings/function_field/function_field_element.pyx
4036 views
1
r"""
2
Function Field Elements
3
4
AUTHORS:
5
6
- William Stein: initial version
7
8
- Robert Bradshaw (2010-05-27): cythonize function field elements
9
10
- Julian Rueth (2011-06-28): treat zero correctly
11
12
- Maarten Derickx (2011-09-11): added doctests, fixed pickling
13
"""
14
#*****************************************************************************
15
# Copyright (C) 2010 William Stein <[email protected]>
16
# Copyright (C) 2010 Robert Bradshaw <[email protected]>
17
# Copyright (C) 2011 Julian Rueth <[email protected]>
18
# Copyright (C) 2011 Maarten Derickx <[email protected]>
19
#
20
# Distributed under the terms of the GNU General Public License (GPL)
21
# as published by the Free Software Foundation; either version 2 of
22
# the License, or (at your option) any later version.
23
# http://www.gnu.org/licenses/
24
#*****************************************************************************
25
26
include "../../ext/stdsage.pxi"
27
28
from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element
29
30
def is_FunctionFieldElement(x):
31
"""
32
Return True if x is any type of function field element.
33
34
EXAMPLES::
35
36
sage: t = FunctionField(QQ,'t').gen()
37
sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(t)
38
True
39
sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(0)
40
False
41
"""
42
if isinstance(x, FunctionFieldElement): return True
43
from function_field import is_FunctionField
44
return is_FunctionField(x.parent())
45
46
def make_FunctionFieldElement(parent, element_class, representing_element):
47
"""
48
Used for unpickling FunctionFieldElement objects (and subclasses).
49
50
EXAMPLES::
51
52
sage: from sage.rings.function_field.function_field_element import make_FunctionFieldElement
53
sage: K.<x> = FunctionField(QQ)
54
sage: make_FunctionFieldElement(K, K._element_class, (x+1)/x)
55
(x + 1)/x
56
"""
57
return element_class(parent, representing_element, reduce=False)
58
59
cdef class FunctionFieldElement(FieldElement):
60
"""
61
The abstract base class for function field elements.
62
63
EXAMPLES::
64
65
sage: t = FunctionField(QQ,'t').gen()
66
sage: isinstance(t, sage.rings.function_field.function_field_element.FunctionFieldElement)
67
True
68
"""
69
70
cdef readonly object _x
71
cdef readonly object _matrix
72
73
def __reduce__(self):
74
"""
75
EXAMPLES::
76
77
sage: K = FunctionField(QQ,'x')
78
sage: f = K.random_element()
79
sage: loads(f.dumps()) == f
80
True
81
"""
82
return (make_FunctionFieldElement,
83
(self._parent, type(self), self._x))
84
85
cdef FunctionFieldElement _new_c(self):
86
cdef FunctionFieldElement x = <FunctionFieldElement>PY_NEW_SAME_TYPE(self)
87
x._parent = self._parent
88
return x
89
90
def _latex_(self):
91
"""
92
EXAMPLES::
93
94
sage: K.<t> = FunctionField(QQ)
95
sage: latex((t+1)/t)
96
\frac{t + 1}{t}
97
sage: latex((t+1)/t^67)
98
\frac{t + 1}{t^{67}}
99
sage: latex((t+1/2)/t^67)
100
\frac{t + \frac{1}{2}}{t^{67}}
101
"""
102
return self._x._latex_()
103
104
def matrix(self):
105
r"""
106
Return the matrix of multiplication by self, interpreting self as an element
107
of a vector space over its base field.
108
109
EXAMPLES:
110
111
A rational function field::
112
113
sage: K.<t> = FunctionField(QQ)
114
sage: t.matrix()
115
[t]
116
sage: (1/(t+1)).matrix()
117
[1/(t + 1)]
118
119
Now an example in a nontrivial extension of a rational function field::
120
121
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
122
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
123
sage: y.matrix()
124
[ 0 1]
125
[-4*x^3 x]
126
sage: y.matrix().charpoly('Z')
127
Z^2 - x*Z + 4*x^3
128
129
An example in a relative extension, where neither function
130
field is rational::
131
132
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
133
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
134
sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - y^2*T + x)
135
sage: alpha.matrix()
136
[ 0 1 0]
137
[ 0 0 1]
138
[ -x x*y - 4*x^3 0]
139
140
We show that this matrix does indeed work as expected when making a
141
vector space from a function field::
142
143
sage: K.<x>=FunctionField(QQ)
144
sage: R.<y> = K[]
145
sage: L.<y> = K.extension(y^5 - (x^3 + 2*x*y + 1/x))
146
sage: V, from_V, to_V = L.vector_space()
147
sage: y5 = to_V(y^5); y5
148
((x^4 + 1)/x, 2*x, 0, 0, 0)
149
sage: y4y = to_V(y^4) * y.matrix(); y4y
150
((x^4 + 1)/x, 2*x, 0, 0, 0)
151
sage: y5 == y4y
152
True
153
"""
154
if self._matrix is None:
155
# Multiply each power of field generator on the left by this
156
# element; make matrix whose rows are the coefficients of the
157
# result, and transpose.
158
K = self.parent()
159
v = []
160
x = K.gen()
161
a = K(1)
162
d = K.degree()
163
for n in range(d):
164
v += (a*self).list()
165
a *= x
166
k = K.base_ring()
167
import sage.matrix.matrix_space
168
M = sage.matrix.matrix_space.MatrixSpace(k, d)
169
self._matrix = M(v)
170
return self._matrix
171
172
def trace(self):
173
"""
174
Return the trace of this function field element.
175
176
EXAMPLES::
177
178
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
179
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
180
sage: y.trace()
181
x
182
"""
183
return self.matrix().trace()
184
185
def norm(self):
186
"""
187
Return the norm of this function field element.
188
189
EXAMPLES::
190
191
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
192
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
193
sage: y.norm()
194
4*x^3
195
196
The norm is relative::
197
198
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
199
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[]
200
sage: M.<z> = L.extension(z^3 - y^2*z + x)
201
sage: z.norm()
202
-x
203
sage: z.norm().parent()
204
Function field in y defined by y^2 - x*y + 4*x^3
205
"""
206
return self.matrix().determinant()
207
208
def characteristic_polynomial(self, *args, **kwds):
209
"""
210
Return the characteristic polynomial of this function field
211
element. Give an optional input string to name the variable
212
in the characteristic polynomial.
213
214
EXAMPLES::
215
216
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
217
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[]
218
sage: M.<z> = L.extension(z^3 - y^2*z + x)
219
sage: x.characteristic_polynomial('W')
220
W - x
221
sage: y.characteristic_polynomial('W')
222
W^2 - x*W + 4*x^3
223
sage: z.characteristic_polynomial('W')
224
W^3 + (-x*y + 4*x^3)*W + x
225
"""
226
return self.matrix().characteristic_polynomial(*args, **kwds)
227
228
charpoly = characteristic_polynomial
229
230
def minimal_polynomial(self, *args, **kwds):
231
"""
232
Return the minimal polynomial of this function field element.
233
Give an optional input string to name the variable in the
234
characteristic polynomial.
235
236
EXAMPLES::
237
238
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
239
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3); R.<z> = L[]
240
sage: M.<z> = L.extension(z^3 - y^2*z + x)
241
sage: x.minimal_polynomial('W')
242
W - x
243
sage: y.minimal_polynomial('W')
244
W^2 - x*W + 4*x^3
245
sage: z.minimal_polynomial('W')
246
W^3 + (-x*y + 4*x^3)*W + x
247
"""
248
return self.matrix().minimal_polynomial(*args, **kwds)
249
250
minpoly = minimal_polynomial
251
252
def is_integral(self):
253
r"""
254
Determine if self is integral over the maximal order of the base field.
255
256
EXAMPLES::
257
258
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
259
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
260
sage: y.is_integral()
261
True
262
sage: (y/x).is_integral()
263
True
264
sage: (y/x)^2 - (y/x) + 4*x
265
0
266
sage: (y/x^2).is_integral()
267
False
268
sage: (y/x).minimal_polynomial('W')
269
W^2 - W + 4*x
270
"""
271
R = self.parent().base_field().maximal_order()
272
return all([a in R for a in self.minimal_polynomial()])
273
274
cdef class FunctionFieldElement_polymod(FunctionFieldElement):
275
"""
276
Elements of a finite extension of a function field.
277
278
EXAMPLES::
279
280
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
281
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
282
sage: x*y + 1/x^3
283
x*y + 1/x^3
284
"""
285
def __init__(self, parent, x, reduce=True):
286
"""
287
EXAMPLES::
288
289
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
290
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
291
sage: type(y)
292
<type 'sage.rings.function_field.function_field_element.FunctionFieldElement_polymod'>
293
"""
294
FieldElement.__init__(self, parent)
295
if reduce:
296
self._x = x % self._parent.polynomial()
297
else:
298
self._x = x
299
300
def element(self):
301
"""
302
Return the underlying polynomial that represents this element.
303
304
EXAMPLES::
305
sage: K.<x> = FunctionField(QQ); R.<T> = K[]
306
sage: L.<y> = K.extension(T^2 - x*T + 4*x^3)
307
sage: f = y/x^2 + x/(x^2+1); f
308
1/x^2*y + x/(x^2 + 1)
309
sage: f.element()
310
1/x^2*T + x/(x^2 + 1)
311
sage: type(f.element())
312
<class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
313
"""
314
return self._x
315
316
def _repr_(self):
317
"""
318
EXAMPLES::
319
320
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
321
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
322
sage: y._repr_()
323
'y'
324
"""
325
return self._x._repr(name=self.parent().variable_name())
326
327
def __nonzero__(self):
328
"""
329
EXAMPLES::
330
331
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
332
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
333
sage: bool(y)
334
True
335
sage: bool(L(0))
336
False
337
sage: bool(L.coerce(L.polynomial()))
338
False
339
"""
340
return not not self._x
341
342
cdef int _cmp_c_impl(self, Element other) except -2:
343
"""
344
EXAMPLES::
345
346
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
347
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
348
sage: cmp(L(0), 0)
349
0
350
sage: cmp(y, L(2)) != 0
351
True
352
"""
353
cdef FunctionFieldElement left = <FunctionFieldElement>self
354
cdef FunctionFieldElement right = <FunctionFieldElement>other
355
return cmp(left._x, right._x)
356
357
cpdef ModuleElement _add_(self, ModuleElement right):
358
"""
359
EXAMPLES::
360
361
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
362
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
363
sage: (2*y + x/(1+x^3)) + (3*y + 5*x*y) # indirect doctest
364
(5*x + 5)*y + x/(x^3 + 1)
365
sage: (y^2 - x*y + 4*x^3)==0 # indirect doctest
366
True
367
sage: -y+y
368
0
369
"""
370
cdef FunctionFieldElement res = self._new_c()
371
res._x = self._x + (<FunctionFieldElement>right)._x
372
return res
373
374
cpdef ModuleElement _sub_(self, ModuleElement right):
375
"""
376
EXAMPLES::
377
378
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
379
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
380
sage: (2*y + x/(1+x^3)) - (3*y + 5*x*y) # indirect doctest
381
(-5*x - 1)*y + x/(x^3 + 1)
382
sage: y-y
383
0
384
"""
385
cdef FunctionFieldElement res = self._new_c()
386
res._x = self._x - (<FunctionFieldElement>right)._x
387
return res
388
389
cpdef RingElement _mul_(self, RingElement right):
390
"""
391
EXAMPLES::
392
393
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
394
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
395
sage: y * (3*y + 5*x*y) # indirect doctest
396
(5*x^2 + 3*x)*y - 20*x^4 - 12*x^3
397
"""
398
cdef FunctionFieldElement res = self._new_c()
399
res._x = (self._x * (<FunctionFieldElement>right)._x) % self._parent.polynomial()
400
return res
401
402
cpdef RingElement _div_(self, RingElement right):
403
"""
404
EXAMPLES::
405
406
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
407
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
408
sage: (2*y + x/(1+x^3)) / (2*y + x/(1+x^3)) # indirect doctest
409
1
410
sage: 1 / (y^2 - x*y + 4*x^3) # indirect doctest
411
Traceback (most recent call last):
412
...
413
ZeroDivisionError: Cannot invert 0
414
"""
415
return self * ~right
416
417
def __invert__(self):
418
"""
419
EXAMPLES::
420
421
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
422
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
423
sage: a = ~(2*y + 1/x); a # indirect doctest
424
(-x^2/(8*x^5 + x^2 + 1/2))*y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
425
sage: a*(2*y + 1/x)
426
1
427
"""
428
if self.is_zero():
429
raise ZeroDivisionError, "Cannot invert 0"
430
P = self._parent
431
return P(self._x.xgcd(P._polynomial)[1])
432
433
def list(self):
434
"""
435
Return a list of coefficients of self, i.e., if self is an element of
436
a function field K[y]/(f(y)), then return the coefficients of the
437
reduced presentation as a polynomial in K[y].
438
439
EXAMPLES::
440
441
sage: K.<x> = FunctionField(QQ); R.<y> = K[]
442
sage: L.<y> = K.extension(y^2 - x*y + 4*x^3)
443
sage: a = ~(2*y + 1/x); a
444
(-x^2/(8*x^5 + x^2 + 1/2))*y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
445
sage: a.list()
446
[(2*x^3 + x)/(16*x^5 + 2*x^2 + 1), -x^2/(8*x^5 + x^2 + 1/2)]
447
sage: (x*y).list()
448
[0, x]
449
"""
450
return self._x.padded_list(self.parent().degree())
451
452
cdef class FunctionFieldElement_rational(FunctionFieldElement):
453
"""
454
Elements of a rational function field.
455
456
EXAMPLES::
457
458
sage: K.<t> = FunctionField(QQ); K
459
Rational function field in t over Rational Field
460
"""
461
def __init__(self, parent, x, reduce=True):
462
"""
463
EXAMPLES::
464
465
sage: FunctionField(QQ,'t').gen()^3
466
t^3
467
"""
468
FieldElement.__init__(self, parent)
469
self._x = x
470
471
def element(self):
472
"""
473
Return the underlying fraction field element that represents this element.
474
475
EXAMPLES::
476
477
sage: K.<t> = FunctionField(GF(7))
478
sage: t.element()
479
t
480
sage: type(t.element())
481
<type 'sage.rings.fraction_field_FpT.FpTElement'>
482
483
sage: K.<t> = FunctionField(GF(131101))
484
sage: t.element()
485
t
486
sage: type(t.element())
487
<class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
488
"""
489
return self._x
490
491
def list(self):
492
"""
493
Return a list of coefficients of self, i.e., if self is an element of
494
a function field K[y]/(f(y)), then return the coefficients of the
495
reduced presentation as a polynomial in K[y].
496
Since self is a member of a rational function field, this simply returns
497
the list `[self]`
498
499
EXAMPLES::
500
501
sage: K.<t> = FunctionField(QQ)
502
sage: t.list()
503
[t]
504
"""
505
return [self]
506
507
def _repr_(self):
508
"""
509
EXAMPLES::
510
511
sage: K.<t> = FunctionField(QQ)
512
sage: t._repr_()
513
't'
514
"""
515
return repr(self._x)
516
517
def __nonzero__(self):
518
"""
519
EXAMPLES::
520
521
sage: K.<t> = FunctionField(QQ)
522
sage: bool(t)
523
True
524
sage: bool(K(0))
525
False
526
sage: bool(K(1))
527
True
528
"""
529
return not not self._x
530
531
cdef int _cmp_c_impl(self, Element other) except -2:
532
"""
533
EXAMPLES::
534
535
sage: K.<t> = FunctionField(QQ)
536
sage: cmp(t, 0)
537
1
538
sage: cmp(t, t^2)
539
-1
540
"""
541
cdef int c = cmp(type(self), type(other))
542
if c: return c
543
cdef FunctionFieldElement left = <FunctionFieldElement>self
544
cdef FunctionFieldElement right = <FunctionFieldElement>other
545
c = cmp(left._parent, right._parent)
546
return c or cmp(left._x, right._x)
547
548
cpdef ModuleElement _add_(self, ModuleElement right):
549
"""
550
EXAMPLES::
551
552
sage: K.<t> = FunctionField(QQ)
553
sage: t + (3*t^3) # indirect doctest
554
3*t^3 + t
555
"""
556
cdef FunctionFieldElement res = self._new_c()
557
res._x = self._x + (<FunctionFieldElement>right)._x
558
return res
559
560
cpdef ModuleElement _sub_(self, ModuleElement right):
561
"""
562
EXAMPLES::
563
564
sage: K.<t> = FunctionField(QQ)
565
sage: t - (3*t^3) # indirect doctest
566
-3*t^3 + t
567
"""
568
cdef FunctionFieldElement res = self._new_c()
569
res._x = self._x - (<FunctionFieldElement>right)._x
570
return res
571
572
cpdef RingElement _mul_(self, RingElement right):
573
"""
574
EXAMPLES::
575
576
sage: K.<t> = FunctionField(QQ)
577
sage: (t+1) * (t^2-1) # indirect doctest
578
t^3 + t^2 - t - 1
579
"""
580
cdef FunctionFieldElement res = self._new_c()
581
res._x = self._x * (<FunctionFieldElement>right)._x
582
return res
583
584
cpdef RingElement _div_(self, RingElement right):
585
"""
586
EXAMPLES::
587
588
sage: K.<t> = FunctionField(QQ)
589
sage: (t+1) / (t^2 - 1) # indirect doctest
590
1/(t - 1)
591
"""
592
cdef FunctionFieldElement res = self._new_c()
593
res._parent = self._parent.fraction_field()
594
res._x = self._x / (<FunctionFieldElement>right)._x
595
return res
596
597
def numerator(self):
598
"""
599
EXAMPLES::
600
601
sage: K.<t> = FunctionField(QQ)
602
sage: f = (t+1) / (t^2 - 1/3); f
603
(t + 1)/(t^2 - 1/3)
604
sage: f.numerator()
605
t + 1
606
"""
607
return self._x.numerator()
608
609
def denominator(self):
610
"""
611
EXAMPLES::
612
613
sage: K.<t> = FunctionField(QQ)
614
sage: f = (t+1) / (t^2 - 1/3); f
615
(t + 1)/(t^2 - 1/3)
616
sage: f.denominator()
617
t^2 - 1/3
618
"""
619
return self._x.denominator()
620
621
def valuation(self, v):
622
"""
623
EXAMPLES::
624
625
sage: K.<t> = FunctionField(QQ)
626
sage: f = (t-1)^2 * (t+1) / (t^2 - 1/3)^3
627
sage: f.valuation(t-1)
628
2
629
sage: f.valuation(t)
630
0
631
sage: f.valuation(t^2 - 1/3)
632
-3
633
"""
634
R = self._parent._ring
635
return self._x.valuation(R(self._parent(v)._x))
636
637
def is_square(self):
638
"""
639
Returns whether self is a square.
640
641
EXAMPLES::
642
643
sage: K.<t> = FunctionField(QQ)
644
sage: t.is_square()
645
False
646
sage: (t^2/4).is_square()
647
True
648
sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square()
649
True
650
651
sage: K.<t> = FunctionField(GF(5))
652
sage: (-t^2).is_square()
653
True
654
sage: (-t^2).sqrt()
655
2*t
656
"""
657
return self._x.is_square()
658
659
def sqrt(self, all=False):
660
"""
661
Returns the square root of self.
662
663
EXAMPLES::
664
665
sage: K.<t> = FunctionField(QQ)
666
sage: f = t^2 - 2 + 1/t^2; f.sqrt()
667
(t^2 - 1)/t
668
sage: f = t^2; f.sqrt(all=True)
669
[t, -t]
670
671
TESTS::
672
673
sage: K(4/9).sqrt()
674
2/3
675
sage: K(0).sqrt(all=True)
676
[0]
677
"""
678
if all:
679
return [self._parent(r) for r in self._x.sqrt(all=True)]
680
else:
681
return self._parent(self._x.sqrt())
682
683
def factor(self):
684
"""
685
Factor this rational function.
686
687
EXAMPLES::
688
689
sage: K.<t> = FunctionField(QQ)
690
sage: f = (t+1) / (t^2 - 1/3)
691
sage: f.factor()
692
(t + 1) * (t^2 - 1/3)^-1
693
sage: (7*f).factor()
694
(7) * (t + 1) * (t^2 - 1/3)^-1
695
sage: ((7*f).factor()).unit()
696
7
697
sage: (f^3).factor()
698
(t + 1)^3 * (t^2 - 1/3)^-3
699
"""
700
P = self.parent()
701
F = self._x.factor()
702
from sage.structure.factorization import Factorization
703
return Factorization([(P(a),e) for a,e in F], unit=F.unit())
704
705
def inverse_mod(self, I):
706
r"""
707
Return an inverse of self modulo the integral ideal `I`, if
708
defined, i.e., if `I` and self together generate the unit
709
ideal.
710
711
EXAMPLES::
712
713
sage: K.<x> = FunctionField(QQ)
714
sage: O = K.maximal_order(); I = O.ideal(x^2+1)
715
sage: t = O(x+1).inverse_mod(I); t
716
-1/2*x + 1/2
717
sage: (t*(x+1) - 1) in I
718
True
719
"""
720
assert len(I.gens()) == 1
721
f = I.gens()[0]._x
722
assert f.denominator() == 1
723
assert self._x.denominator() == 1
724
return self.parent()(self._x.numerator().inverse_mod(f.numerator()))
725
726