Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/categories/fields.py
8817 views
1
r"""
2
Fields
3
"""
4
#*****************************************************************************
5
# Copyright (C) 2005 David Kohel <[email protected]>
6
# William Stein <[email protected]>
7
# 2008 Teresa Gomez-Diaz (CNRS) <[email protected]>
8
# 2008-2009 Nicolas M. Thiery <nthiery at users.sf.net>
9
# 2012 Julian Rueth <[email protected]>
10
#
11
# Distributed under the terms of the GNU General Public License (GPL)
12
# http://www.gnu.org/licenses/
13
#******************************************************************************
14
15
from sage.categories.category import Category
16
from sage.categories.category_singleton import Category_singleton, Category_contains_method_by_parent_class
17
from sage.categories.euclidean_domains import EuclideanDomains
18
from sage.categories.unique_factorization_domains import UniqueFactorizationDomains
19
from sage.categories.division_rings import DivisionRings
20
21
from sage.misc.cachefunc import cached_method
22
from sage.misc.lazy_attribute import lazy_class_attribute
23
import sage.rings.ring
24
from sage.structure.element import coerce_binop
25
26
class Fields(Category_singleton):
27
"""
28
The category of (commutative) fields, i.e. commutative rings where
29
all non-zero elements have multiplicative inverses
30
31
EXAMPLES::
32
33
sage: K = Fields()
34
sage: K
35
Category of fields
36
sage: Fields().super_categories()
37
[Category of euclidean domains, Category of unique factorization domains, Category of division rings]
38
39
sage: K(IntegerRing())
40
Rational Field
41
sage: K(PolynomialRing(GF(3), 'x'))
42
Fraction Field of Univariate Polynomial Ring in x over
43
Finite Field of size 3
44
sage: K(RealField())
45
Real Field with 53 bits of precision
46
47
TESTS::
48
49
sage: TestSuite(Fields()).run()
50
"""
51
52
def super_categories(self):
53
"""
54
EXAMPLES::
55
56
sage: Fields().super_categories()
57
[Category of euclidean domains, Category of unique factorization domains, Category of division rings]
58
59
"""
60
return [EuclideanDomains(), UniqueFactorizationDomains(), DivisionRings()]
61
62
def __contains__(self, x):
63
"""
64
EXAMPLES::
65
66
sage: GF(4, "a") in Fields()
67
True
68
sage: QQ in Fields()
69
True
70
sage: ZZ in Fields()
71
False
72
sage: IntegerModRing(4) in Fields()
73
False
74
sage: InfinityRing in Fields()
75
False
76
77
This implementation will not be needed anymore once every
78
field in Sage will be properly declared in the category
79
:class:`Fields`().
80
81
Caveat: this should eventually be fixed::
82
83
sage: gap.Rationals in Fields()
84
False
85
86
typically by implementing the method :meth:`category`
87
appropriately for Gap objects::
88
89
sage: GR = gap.Rationals
90
sage: GR.category = lambda : Fields()
91
sage: GR in Fields()
92
True
93
94
The following tests against a memory leak fixed in :trac:`13370`::
95
96
sage: import gc
97
sage: _ = gc.collect()
98
sage: n = len([X for X in gc.get_objects() if isinstance(X, sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic)])
99
sage: for i in prime_range(100):
100
... R = ZZ.quotient(i)
101
... t = R in Fields()
102
sage: _ = gc.collect()
103
sage: len([X for X in gc.get_objects() if isinstance(X, sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic)]) - n
104
1
105
106
"""
107
try:
108
return self._contains_helper(x) or sage.rings.ring._is_Field(x)
109
except Exception:
110
return False
111
112
@lazy_class_attribute
113
def _contains_helper(cls):
114
"""
115
Helper for containment tests in the category of fields.
116
117
This helper just tests whether the given object's category
118
is already known to be a sub-category of the category of
119
fields. There are, however, rings that are initialised
120
as plain commutative rings and found out to be fields
121
only afterwards. Hence, this helper alone is not enough
122
for a proper containment test.
123
124
TESTS::
125
126
sage: P.<x> = QQ[]
127
sage: Q = P.quotient(x^2+2)
128
sage: Q.category()
129
Join of Category of commutative algebras over Rational Field and Category of subquotients of monoids and Category of quotients of semigroups
130
sage: F = Fields()
131
sage: F._contains_helper(Q)
132
False
133
sage: Q in F # This changes the category!
134
True
135
sage: F._contains_helper(Q)
136
True
137
138
"""
139
return Category_contains_method_by_parent_class(cls())
140
141
def _call_(self, x):
142
"""
143
Construct a field from the data in ``x``
144
145
EXAMPLES::
146
147
sage: K = Fields()
148
sage: K
149
Category of fields
150
sage: Fields().super_categories()
151
[Category of euclidean domains, Category of unique factorization domains, Category of division rings]
152
153
sage: K(IntegerRing()) # indirect doctest
154
Rational Field
155
sage: K(PolynomialRing(GF(3), 'x')) # indirect doctest
156
Fraction Field of Univariate Polynomial Ring in x over
157
Finite Field of size 3
158
sage: K(RealField())
159
Real Field with 53 bits of precision
160
"""
161
try:
162
return x.fraction_field()
163
except AttributeError:
164
raise TypeError, "unable to associate a field to %s"%x
165
166
class ParentMethods:
167
def is_field(self):
168
"""
169
Return True, since this in an object of the category of fields.
170
171
EXAMPLES::
172
173
sage: Parent(QQ,category=Fields()).is_field()
174
True
175
176
"""
177
return True
178
179
def is_integrally_closed(self):
180
r"""
181
182
Return ``True``, as per :meth:`IntegralDomain.is_integraly_closed`:
183
for every field `F`, `F` is its own field of fractions,
184
hence every element of `F` is integral over `F`.
185
186
EXAMPLES::
187
188
sage: QQ.is_integrally_closed()
189
True
190
sage: QQbar.is_integrally_closed()
191
True
192
sage: Z5 = GF(5); Z5
193
Finite Field of size 5
194
sage: Z5.is_integrally_closed()
195
True
196
"""
197
return True
198
199
def _test_characteristic_fields(self, **options):
200
"""
201
Run generic tests on the method :meth:`.characteristic`.
202
203
EXAMPLES::
204
205
sage: QQ._test_characteristic_fields()
206
207
.. NOTE::
208
209
We cannot call this method ``_test_characteristic`` since that
210
would overwrite the method in the super category, and for
211
cython classes just calling
212
``super(sage.categories.fields.Fields().parent_class,
213
self)._test_characteristic`` doesn't have the desired effect.
214
215
.. SEEALSO::
216
217
:meth:`sage.categories.rings.Rings.ParentMethods._test_characteristic`
218
"""
219
tester = self._tester(**options)
220
try:
221
char = self.characteristic()
222
tester.assertTrue(char.is_zero() or char.is_prime())
223
except AttributeError:
224
return
225
# raised when self.one() does not have a additive_order() [or when char is an int and not an Integer which is already checked by _test_characteristic for rings]
226
except NotImplementedError:
227
return
228
229
def is_integral_domain(self):
230
r"""
231
232
Returns ``True``, as fields are integral domains.
233
234
EXAMPLES::
235
236
sage: QQ.is_integral_domain()
237
True
238
"""
239
return True
240
241
def is_field( self, proof=True ):
242
r"""
243
Returns True as ``self`` is a field.
244
245
EXAMPLES::
246
247
sage: QQ.is_field()
248
True
249
"""
250
return True
251
252
def fraction_field(self):
253
r"""
254
Returns the *fraction field* of ``self``, which is ``self``.
255
256
EXAMPLES::
257
258
sage: QQ.fraction_field() is QQ
259
True
260
"""
261
return self
262
263
def __pow__(self, n):
264
r"""
265
Returns the vector space of dimension `n` over ``self``.
266
267
EXAMPLES::
268
269
sage: QQ^4
270
Vector space of dimension 4 over Rational Field
271
"""
272
from sage.modules.all import FreeModule
273
return FreeModule(self, n)
274
275
class ElementMethods:
276
277
def is_unit( self ):
278
r"""
279
Returns True if ``self`` has a multiplicative inverse.
280
281
EXAMPLES::
282
283
sage: QQ(2).is_unit()
284
True
285
sage: QQ(0).is_unit()
286
False
287
"""
288
return not self.is_zero()
289
290
# Fields are unique factorization domains, so, there is gcd and lcm
291
# Of course, in general gcd and lcm in a field are not very interesting.
292
# However, they should be implemented!
293
def gcd(self,other):
294
"""
295
Greatest common divisor.
296
297
NOTE:
298
299
Since we are in a field and the greatest common divisor is
300
only determined up to a unit, it is correct to either return
301
zero or one. Note that fraction fields of unique factorization
302
domains provide a more sophisticated gcd.
303
304
EXAMPLES::
305
306
sage: GF(5)(1).gcd(GF(5)(1))
307
1
308
sage: GF(5)(1).gcd(GF(5)(0))
309
1
310
sage: GF(5)(0).gcd(GF(5)(0))
311
0
312
313
For fields of characteristic zero (i.e., containing the
314
integers as a sub-ring), evaluation in the integer ring is
315
attempted. This is for backwards compatibility::
316
317
sage: gcd(6.0,8); gcd(6.0,8).parent()
318
2
319
Integer Ring
320
321
If this fails, we resort to the default we see above::
322
323
sage: gcd(6.0*CC.0,8*CC.0); gcd(6.0*CC.0,8*CC.0).parent()
324
1.00000000000000
325
Complex Field with 53 bits of precision
326
327
AUTHOR:
328
329
- Simon King (2011-02): Trac ticket #10771
330
331
"""
332
P = self.parent()
333
try:
334
other = P(other)
335
except (TypeError, ValueError):
336
raise ArithmeticError, "The second argument can not be interpreted in the parent of the first argument. Can't compute the gcd"
337
from sage.rings.integer_ring import ZZ
338
if ZZ.is_subring(P):
339
try:
340
return ZZ(self).gcd(ZZ(other))
341
except TypeError:
342
pass
343
# there is no custom gcd, so, we resort to something that always exists
344
# (that's new behaviour)
345
if self==0 and other==0:
346
return P.zero()
347
return P.one()
348
349
def lcm(self,other):
350
"""
351
Least common multiple.
352
353
NOTE:
354
355
Since we are in a field and the least common multiple is
356
only determined up to a unit, it is correct to either return
357
zero or one. Note that fraction fields of unique factorization
358
domains provide a more sophisticated lcm.
359
360
EXAMPLES::
361
362
sage: GF(2)(1).lcm(GF(2)(0))
363
0
364
sage: GF(2)(1).lcm(GF(2)(1))
365
1
366
367
If the field contains the integer ring, it is first
368
attempted to compute the gcd there::
369
370
sage: lcm(15.0,12.0); lcm(15.0,12.0).parent()
371
60
372
Integer Ring
373
374
If this fails, we resort to the default we see above::
375
376
sage: lcm(6.0*CC.0,8*CC.0); lcm(6.0*CC.0,8*CC.0).parent()
377
1.00000000000000
378
Complex Field with 53 bits of precision
379
sage: lcm(15.2,12.0)
380
1.00000000000000
381
382
AUTHOR:
383
384
- Simon King (2011-02): Trac ticket #10771
385
386
"""
387
P = self.parent()
388
try:
389
other = P(other)
390
except (TypeError, ValueError):
391
raise ArithmeticError, "The second argument can not be interpreted in the parent of the first argument. Can't compute the lcm"
392
from sage.rings.integer_ring import ZZ
393
if ZZ.is_subring(P):
394
try:
395
return ZZ(self).lcm(ZZ(other))
396
except TypeError:
397
pass
398
# there is no custom lcm, so, we resort to something that always exists
399
if self==0 or other==0:
400
return P.zero()
401
return P.one()
402
403
@coerce_binop
404
def xgcd(self, other):
405
"""
406
Compute the extended gcd of ``self`` and ``other``.
407
408
INPUT:
409
410
- ``other`` -- an element with the same parent as ``self``
411
412
OUTPUT:
413
414
A tuple ``(r, s, t)`` of elements in the parent of ``self`` such
415
that ``r = s * self + t * other``. Since the computations are done
416
over a field, ``r`` is zero if ``self`` and ``other`` are zero,
417
and one otherwise.
418
419
AUTHORS:
420
421
- Julian Rueth (2012-10-19): moved here from
422
:class:`sage.structure.element.FieldElement`
423
424
EXAMPLES::
425
426
sage: (1/2).xgcd(2)
427
(1, 2, 0)
428
sage: (0/2).xgcd(2)
429
(1, 0, 1/2)
430
sage: (0/2).xgcd(0)
431
(0, 0, 0)
432
"""
433
R = self.parent()
434
if not self.is_zero():
435
return (R.one(), ~self, R.zero())
436
if not other.is_zero():
437
return (R.one(), R.zero(), ~other)
438
# else both are 0
439
return (R.zero(), R.zero(), R.zero())
440
441
442