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
include "stdsage.pxi"
24
25
from sage.structure.element cimport FieldElement, RingElement, ModuleElement, Element
26
27
def is_FunctionFieldElement(x):
28
"""
29
Return True if x is any type of function field element.
30
31
EXAMPLES::
32
33
sage: t = FunctionField(QQ,'t').gen()
34
sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(t)
35
True
36
sage: sage.rings.function_field.function_field_element.is_FunctionFieldElement(0)
37
False
38
"""
39
return isinstance(x, FunctionFieldElement)
40
41
cdef class FunctionFieldElement(FieldElement):
42
43
cdef readonly object _x
44
cdef readonly object _matrix
45
46
"""
47
The abstract base class for function field elements.
48
49
EXAMPLES::
50
51
sage: t = FunctionField(QQ,'t').gen()
52
sage: isinstance(t, sage.rings.function_field.function_field_element.FunctionFieldElement)
53
True
54
"""
55
56
cdef FunctionFieldElement _new_c(self):
57
cdef FunctionFieldElement x = <FunctionFieldElement>PY_NEW_SAME_TYPE(self)
58
x._parent = self._parent
59
return x
60
61
def __call__(self, x):
62
return self.numerator()(x) / self.denominator()(x)
63
64
def _latex_(self):
65
"""
66
EXAMPLES::
67
68
sage: K.<t> = FunctionField(QQ)
69
sage: latex((t+1)/t)
70
\frac{t + 1}{t}
71
sage: latex((t+1)/t^67)
72
\frac{t + 1}{t^{67}}
73
sage: latex((t+1/2)/t^67)
74
\frac{t + \frac{1}{2}}{t^{67}}
75
"""
76
return self._x._latex_()
77
78
def matrix(self):
79
r"""
80
Return the matrix of multiplication by self.
81
82
EXAMPLES::
83
84
A rational function field:
85
86
sage: K.<t> = FunctionField(QQ)
87
sage: t.matrix()
88
[t]
89
sage: (1/(t+1)).matrix()
90
[1/(t + 1)]
91
92
Now an example in a nontrivial extension of a rational function field::
93
94
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
95
sage: Y.matrix()
96
[ 0 1]
97
[-4*x^3 x]
98
sage: Y.matrix().charpoly('Z')
99
Z^2 - x*Z + 4*x^3
100
101
An example in a relative extension, where neither function
102
field is rational::
103
104
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
105
sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
106
sage: alpha.matrix()
107
[ 0 1 0]
108
[ 0 0 1]
109
[ -x x*Y - 4*x^3 0]
110
"""
111
if self._matrix is None:
112
# Multiply each power of field generator on the left by this
113
# element; make matrix whose rows are the coefficients of the
114
# result, and transpose.
115
K = self.parent()
116
v = []
117
x = K.gen()
118
a = K(1)
119
d = K.degree()
120
for n in range(d):
121
v += (a*self).list()
122
a *= x
123
k = K.base_ring()
124
import sage.matrix.matrix_space
125
M = sage.matrix.matrix_space.MatrixSpace(k, d)
126
self._matrix = M(v)
127
return self._matrix
128
129
def trace(self):
130
"""
131
Return the trace of this function field element.
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: Y.trace()
137
x
138
"""
139
return self.matrix().trace()
140
141
def norm(self):
142
"""
143
Return the norm of this function field element.
144
145
EXAMPLES::
146
147
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
148
sage: Y.norm()
149
4*x^3
150
151
152
The norm is relative::
153
154
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
155
sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
156
sage: alpha.norm()
157
-x
158
sage: alpha.norm().parent()
159
Function field in Y defined by y^2 - x*y + 4*x^3
160
"""
161
return self.matrix().determinant()
162
163
def characteristic_polynomial(self, *args, **kwds):
164
"""
165
Return the characteristic polynomial of this function field
166
element. Give an optional input string to name the variable
167
in the characteristic polynomial.
168
169
EXAMPLES::
170
171
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
172
sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
173
sage: x.characteristic_polynomial('W')
174
W - x
175
sage: Y.characteristic_polynomial('W')
176
W^2 - x*W + 4*x^3
177
sage: alpha.characteristic_polynomial('W')
178
W^3 + (-x*Y + 4*x^3)*W + x
179
"""
180
return self.matrix().characteristic_polynomial(*args, **kwds)
181
182
charpoly = characteristic_polynomial
183
184
def minimal_polynomial(self, *args, **kwds):
185
"""
186
Return the minimal polynomial of this function field element.
187
Give an optional input string to name the variable in the
188
characteristic polynomial.
189
190
EXAMPLES::
191
192
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
193
sage: M.<T> = L[]; Z.<alpha> = L.extension(T^3 - Y^2*T + x)
194
sage: x.minimal_polynomial('W')
195
W - x
196
sage: Y.minimal_polynomial('W')
197
W^2 - x*W + 4*x^3
198
sage: alpha.minimal_polynomial('W')
199
W^3 + (-x*Y + 4*x^3)*W + x
200
"""
201
return self.matrix().minimal_polynomial(*args, **kwds)
202
203
minpoly = minimal_polynomial
204
205
def is_integral(self):
206
r"""
207
Determine if self is integral over the maximal order of the base field.
208
209
EXAMPLES::
210
211
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
212
sage: Y.is_integral()
213
True
214
sage: (Y/x).is_integral()
215
True
216
sage: (Y/x)^2 - (Y/x) + 4*x
217
0
218
sage: (Y/x^2).is_integral()
219
False
220
sage: f = (Y/x).minimal_polynomial('W'); f
221
W^2 - W + 4*x
222
"""
223
R = self.parent().base_field().maximal_order()
224
return all([a in R for a in self.minimal_polynomial()])
225
226
cdef class FunctionFieldElement_polymod(FunctionFieldElement):
227
"""
228
EXAMPLES::
229
230
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
231
sage: x*Y + 1/x^3
232
x*Y + 1/x^3
233
"""
234
def __init__(self, parent, x):
235
"""
236
EXAMPLES::
237
238
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
239
sage: type(Y)
240
<type 'sage.rings.function_field.function_field_element.FunctionFieldElement_polymod'>
241
"""
242
FieldElement.__init__(self, parent)
243
self._x = x
244
245
def element(self):
246
"""
247
Return the underlying polynomial that represents this element.
248
249
EXAMPLES::
250
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
251
sage: f = Y/x^2 + x/(x^2+1); f
252
1/x^2*Y + x/(x^2 + 1)
253
sage: f.element()
254
1/x^2*y + x/(x^2 + 1)
255
sage: type(f.element())
256
<class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
257
"""
258
return self._x
259
260
def _repr_(self):
261
"""
262
EXAMPLES::
263
264
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
265
sage: Y._repr_()
266
'Y'
267
"""
268
return self._x._repr(name=self.parent().variable_name())
269
270
def __nonzero__(self):
271
"""
272
EXAMPLES::
273
274
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
275
sage: bool(Y)
276
True
277
sage: bool(L(0))
278
False
279
"""
280
return not not self._x
281
282
cdef int _cmp_c_impl(self, Element other) except -2:
283
"""
284
EXAMPLES::
285
286
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
287
sage: cmp(L, 0)
288
1
289
sage: cmp(0, L)
290
-1
291
"""
292
cdef int c = cmp(type(self), type(other))
293
if c: return c
294
cdef FunctionFieldElement left = <FunctionFieldElement>self
295
cdef FunctionFieldElement right = <FunctionFieldElement>other
296
c = cmp(left._parent, right._parent)
297
return c or cmp(left._x, right._x)
298
299
cpdef ModuleElement _add_(self, ModuleElement right):
300
"""
301
EXAMPLES::
302
303
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
304
sage: (2*Y + x/(1+x^3)) + (3*Y + 5*x*Y) # indirect doctest
305
(5*x + 5)*Y + x/(x^3 + 1)
306
"""
307
cdef FunctionFieldElement res = self._new_c()
308
res._x = self._x + (<FunctionFieldElement>right)._x
309
return res
310
311
cpdef ModuleElement _sub_(self, ModuleElement right):
312
"""
313
EXAMPLES::
314
315
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
316
sage: (2*Y + x/(1+x^3)) - (3*Y + 5*x*Y) # indirect doctest
317
(-5*x - 1)*Y + x/(x^3 + 1)
318
"""
319
cdef FunctionFieldElement res = self._new_c()
320
res._x = self._x - (<FunctionFieldElement>right)._x
321
return res
322
323
cpdef RingElement _mul_(self, RingElement right):
324
"""
325
EXAMPLES::
326
327
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
328
sage: Y * (3*Y + 5*x*Y) # indirect doctest
329
(5*x^2 + 3*x)*Y - 20*x^4 - 12*x^3
330
"""
331
cdef FunctionFieldElement res = self._new_c()
332
res._x = (self._x * (<FunctionFieldElement>right)._x) % self._parent.polynomial()
333
return res
334
335
cpdef RingElement _div_(self, RingElement right):
336
"""
337
EXAMPLES::
338
339
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
340
sage: (2*Y + x/(1+x^3)) / (2*Y + x/(1+x^3)) # indirect doctest
341
1
342
"""
343
return self * ~right
344
345
def __invert__(self):
346
"""
347
EXAMPLES::
348
349
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
350
sage: a = ~(2*Y + 1/x); a # indirect doctest
351
(-x^2/(8*x^5 + x^2 + 1/2))*Y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
352
sage: a*(2*Y + 1/x)
353
1
354
"""
355
P = self._parent
356
return P(self._x.xgcd(P._polynomial)[1])
357
358
def list(self):
359
"""
360
EXAMPLES::
361
362
sage: K.<x> = FunctionField(QQ); R.<y> = K[]; L.<Y> = K.extension(y^2 - x*y + 4*x^3)
363
sage: a = ~(2*Y + 1/x); a
364
(-x^2/(8*x^5 + x^2 + 1/2))*Y + (2*x^3 + x)/(16*x^5 + 2*x^2 + 1)
365
sage: a.list()
366
[(2*x^3 + x)/(16*x^5 + 2*x^2 + 1), -x^2/(8*x^5 + x^2 + 1/2)]
367
sage: (x*Y).list()
368
[0, x]
369
"""
370
return self._x.padded_list(self.parent().degree())
371
372
373
cdef class FunctionFieldElement_rational(FunctionFieldElement):
374
"""
375
EXAMPLES::
376
377
sage: FunctionField(QQ, 't')
378
Rational function field in t over Rational Field
379
"""
380
def __init__(self, parent, x):
381
"""
382
EXAMPLES::
383
384
sage: FunctionField(QQ,'t').gen()^3
385
t^3
386
"""
387
FieldElement.__init__(self, parent)
388
self._x = x
389
390
# nonoptimized
391
392
def element(self):
393
"""
394
Return the underlying fraction field element that represents this element.
395
396
EXAMPLES::
397
398
sage: R.<a> = FunctionField(GF(7))
399
sage: a.element()
400
a
401
sage: type(a.element())
402
<type 'sage.rings.fraction_field_element.FractionFieldElement'>
403
"""
404
return self._x
405
406
def list(self):
407
"""
408
EXAMPLES::
409
410
sage: K.<t> = FunctionField(QQ)
411
sage: t.list()
412
[t]
413
"""
414
return [self]
415
416
def _repr_(self):
417
"""
418
EXAMPLES::
419
420
sage: K.<t> = FunctionField(QQ)
421
sage: t._repr_()
422
't'
423
"""
424
return repr(self._x)
425
426
def __nonzero__(self):
427
"""
428
EXAMPLES::
429
430
sage: K.<t> = FunctionField(QQ)
431
sage: bool(t)
432
True
433
sage: bool(K(0))
434
False
435
sage: bool(K(1))
436
True
437
"""
438
return not not self._x
439
440
cdef int _cmp_c_impl(self, Element other) except -2:
441
"""
442
EXAMPLES::
443
444
sage: K.<t> = FunctionField(QQ)
445
sage: cmp(t, 0)
446
1
447
sage: cmp(t, t^2)
448
-1
449
"""
450
cdef int c = cmp(type(self), type(other))
451
if c: return c
452
cdef FunctionFieldElement left = <FunctionFieldElement>self
453
cdef FunctionFieldElement right = <FunctionFieldElement>other
454
c = cmp(left._parent, right._parent)
455
return c or cmp(left._x, right._x)
456
457
cpdef ModuleElement _add_(self, ModuleElement right):
458
"""
459
EXAMPLES::
460
461
sage: K.<t> = FunctionField(QQ)
462
sage: t + (3*t^3) # indirect doctest
463
3*t^3 + t
464
"""
465
cdef FunctionFieldElement res = self._new_c()
466
res._x = self._x + (<FunctionFieldElement>right)._x
467
return res
468
469
cpdef ModuleElement _sub_(self, ModuleElement right):
470
"""
471
EXAMPLES::
472
473
474
sage: K.<t> = FunctionField(QQ)
475
sage: t - (3*t^3) # indirect doctest
476
-3*t^3 + t
477
"""
478
cdef FunctionFieldElement res = self._new_c()
479
res._x = self._x - (<FunctionFieldElement>right)._x
480
return res
481
482
cpdef RingElement _mul_(self, RingElement right):
483
"""
484
EXAMPLES::
485
486
sage: K.<t> = FunctionField(QQ)
487
sage: (t+1) * (t^2-1) # indirect doctest
488
t^3 + t^2 - t - 1
489
"""
490
cdef FunctionFieldElement res = self._new_c()
491
res._x = self._x * (<FunctionFieldElement>right)._x
492
return res
493
494
cpdef RingElement _div_(self, RingElement right):
495
"""
496
EXAMPLES::
497
498
sage: K.<t> = FunctionField(QQ)
499
sage: (t+1) / (t^2 - 1) # indirect doctest
500
1/(t - 1)
501
"""
502
cdef FunctionFieldElement res = self._new_c()
503
res._parent = self._parent.fraction_field()
504
res._x = self._x / (<FunctionFieldElement>right)._x
505
return res
506
507
def numerator(self):
508
"""
509
EXAMPLES::
510
511
sage: K.<t> = FunctionField(QQ)
512
sage: f = (t+1) / (t^2 - 1/3); f
513
(t + 1)/(t^2 - 1/3)
514
sage: f.numerator()
515
t + 1
516
"""
517
return self._x.numerator()
518
519
def denominator(self):
520
"""
521
EXAMPLES::
522
523
sage: K.<t> = FunctionField(QQ)
524
sage: f = (t+1) / (t^2 - 1/3); f
525
(t + 1)/(t^2 - 1/3)
526
sage: f.denominator()
527
t^2 - 1/3
528
"""
529
return self._x.denominator()
530
531
def valuation(self, v):
532
"""
533
EXAMPLES::
534
535
sage: K.<t> = FunctionField(QQ)
536
sage: f = (t-1)^2 * (t+1) / (t^2 - 1/3)^3
537
sage: f.valuation(t-1)
538
2
539
sage: f.valuation(t)
540
0
541
sage: f.valuation(t^2 - 1/3)
542
-3
543
"""
544
R = self._parent._ring
545
return self._x.valuation(R(self._parent(v)._x))
546
547
def is_square(self):
548
"""
549
Returns whether self is a square.
550
551
EXAMPLES::
552
553
sage: K.<t> = FunctionField(QQ)
554
sage: t.is_square()
555
False
556
sage: (t^2/4).is_square()
557
True
558
sage: f = 9 * (t+1)^6 / (t^2 - 2*t + 1); f.is_square()
559
True
560
561
sage: K.<t> = FunctionField(GF(5))
562
sage: (-t^2).is_square()
563
True
564
sage: (-t^2).sqrt()
565
2*t
566
"""
567
return self._x.is_square()
568
569
def sqrt(self, all=False):
570
"""
571
Returns the square root of self.
572
573
EXMPLES::
574
575
sage: K.<t> = FunctionField(QQ)
576
sage: f = t^2 - 2 + 1/t^2; f.sqrt()
577
(t^2 - 1)/t
578
sage: f = t^2; f.sqrt(all=True)
579
[t, -t]
580
581
TESTS::
582
583
sage: K(4/9).sqrt()
584
2/3
585
sage: K(0).sqrt(all=True)
586
[0]
587
"""
588
if all:
589
return [self._parent(r) for r in self._x.sqrt(all=True)]
590
else:
591
return self._parent(self._x.sqrt())
592
593
def factor(self):
594
"""
595
Factor this rational function.
596
597
EXAMPLES::
598
599
sage: K.<t> = FunctionField(QQ)
600
sage: f = (t+1) / (t^2 - 1/3)
601
sage: f.factor()
602
(t + 1) * (t^2 - 1/3)^-1
603
sage: (7*f).factor()
604
(7) * (t + 1) * (t^2 - 1/3)^-1
605
sage: ((7*f).factor()).unit()
606
7
607
sage: (f^3).factor()
608
(t + 1)^3 * (t^2 - 1/3)^-3
609
"""
610
P = self.parent()
611
F = self._x.factor()
612
from sage.structure.factorization import Factorization
613
return Factorization([(P(a),e) for a,e in F], unit=F.unit())
614
615
def inverse_mod(self, I):
616
r"""
617
Return an inverse of self modulo the integral ideal `I`, if
618
defined, i.e., if `I` and self together generate the unit
619
ideal.
620
621
EXAMPLES::
622
623
sage: R.<x> = FunctionField(QQ)
624
sage: S = R.maximal_order(); I = S.ideal(x^2+1)
625
sage: t = S(x+1).inverse_mod(I); t
626
-1/2*x + 1/2
627
sage: (t*(x+1) - 1) in I
628
True
629
"""
630
f = I.gens()[0]._x
631
assert f.denominator() == 1
632
assert self._x.denominator() == 1
633
return self.parent()(self._x.numerator().inverse_mod(f.numerator()))
634
635