source: sage/rings/extended_rational_field.py @ 6140:2fb4b1da68ab

Revision 6140:2fb4b1da68ab, 12.3 KB checked in by William Stein <wstein@…>, 6 years ago (diff)

Working on improving basic structure of number fields.

Line 
1import sage.rings.rational_field
2import sage.rings.rational
3import sage.rings.integer
4import sage.rings.infinity
5import sage.structure.element
6import sage.rings.extended_integer_ring
7import field
8from sage.structure.parent_gens import ParentWithGens
9
10Rational = sage.rings.rational.Rational
11RationalField = sage.rings.rational_field.RationalField
12Integer = sage.rings.integer.Integer
13InfinityElement = sage.structure.element.InfinityElement
14PlusInfinityElement = sage.structure.element.PlusInfinityElement
15MinusInfinityElement = sage.structure.element.MinusInfinityElement
16ExtendedIntegerRing = sage.rings.extended_integer_ring.ExtendedIntegerRing
17IntegerPlusInfinity = sage.rings.extended_integer_ring.IntegerPlusInfinity
18IntegerMinusInfinity = sage.rings.extended_integer_ring.IntegerMinusInfinity
19SignError = sage.rings.infinity.SignError
20
21_obj = {}
22class _uniq0(object):
23    def __new__(cls):
24        if _obj.has_key(0):
25            return _obj[0]
26        O = RationalField.__new__(cls)
27        _obj[0] = O
28        return O
29
30class _uniq1(object):
31    def __new__(cls):
32        if _obj.has_key(1):
33            return _obj[1]
34        O = PlusInfinityElement.__new__(cls)
35        _obj[1] = O
36        return O
37
38class _uniq2(object):
39    def __new__(cls):
40        if _obj.has_key(2):
41            return _obj[2]
42        O = MinusInfinityElement.__new__(cls)
43        _obj[2] = O
44        return O
45
46class ExtendedRationalField_class(_uniq0, RationalField):
47    def __init__(self):
48        ParentWithGens.__init__(self, self)
49        self._assign_names(('x'),normalize=False)
50   
51    def _repr_(self):
52        return "Extended Rational Field"
53
54    def _latex_(self):
55        return "\\mathbf{Q}\\cup\\{\\pm\\infty\\}"
56
57    def __call__(self, x, base = 0):
58        if isinstance(x, sage.rings.infinity.MinusInfinity):
59            return self.gen(2)
60        if isinstance(x, sage.structure.element.InfinityElement):
61            return self.gen(1)
62        if isinstance(x, sage.rings.infinity.FiniteNumber):
63            if x == 0:
64                return ExtendedRational(0)
65            raise TypeError, "cannot coerce unknown finite number into the extended rationals"
66        return ExtendedRational(x, base)
67
68    def _coerce_impl(self, x):
69        if isinstance(x, (int, long, sage.rings.integer.Integer, Rational)):
70            return self(x)
71        if isinstance(x, (IntegerPlusInfinity, IntegerMinusInfinity)):
72            return self(x)
73        raise TypeError, "no implicit coercion of element to the rational numbers"
74
75    def _is_valid_homomorphism(self, codomain, im_gens):
76        raise NotImplementedError
77
78    def __iter__(self):
79        yield self(0)
80        yield self(1)
81        yield self(-1)
82        yield self.gen(1)
83        yield self.gen(2)
84        from integer_ring import IntegerRing
85        for n in IntegerRing():
86            m = abs(n)
87            for d in abs(n).coprime_integers(m):
88                yield n/d
89                yield d/n
90
91    def complex_embedding(self, prec=53):
92        raise NotImplementedError
93
94    def gens(self):
95        return (self(1), self.gen(1), self.gen(2), )
96
97    def gen(self, n=0):
98        if n == 0:
99            return self(1)
100        elif n == 1:
101            try:
102                return self.gen1
103            except AttributeError:
104                self.gen1 = RationalPlusInfinity()
105                return self.gen1
106        elif n == 2:
107            try:
108                return self.gen2
109            except AttributeError:
110                self.gen2 = RationalMinusInfinity()
111                return self.gen2
112        else:
113            raise IndexError, "n must be 0, 1 or 2"
114
115    def is_prime_field(self):
116        return False
117
118    def ngens(self):
119        return 3
120
121    def numberfield(self, poly_var, nf_var):
122        raise NotImplementedError
123
124ExtendedRationalField = ExtendedRationalField_class()
125
126class ExtendedRational(Rational):
127    def __init__(self, x = None, base = 0):
128        Rational.__init__(self, x, base)
129        self._set_parent(ExtendedRationalField)
130
131    def __cmp__(self, other):
132        if isinstance(other, InfinityElement):
133            return -other.__cmp__(self)
134        return cmp(Rational(self), Rational(other))
135
136    def copy(self):
137        return self.parent()(Rational.copy(self))
138
139    def lcm(self, other):
140        if isinstance(other, InfinityElement):
141            return self.parent().gen(1)
142        else:
143            return self.parent()(Rational.lcm(self, other))
144
145    def square_root(self):
146        return self.parent()(Rational.square_root(self))
147
148    def nth_root(self):
149        return self.parent()(Rational.nth_root(self))
150
151    def _add_(self, right):
152        if isinstance(right, InfinityElement):
153            return right
154        return self.parent()(Rational(self) + Rational(right))
155
156    def _sub_(self, right):
157        if isinstance(right, InfinityElement):
158            return -right
159        return self.parent()(Rational(self) - Rational(right))
160
161    def _neg_(self):
162        return self.parent()(-Rational(self))
163
164    def _mul_(self, right):
165        if isinstance(right, InfinityElement):
166            return right._mul_(self)
167        return self.parent()(Rational(self) * Rational(right))
168
169    def _div_(self, right):
170        if isinstance(right, InfinityElement):
171            return self.parent()(0)
172        return self.parent()(Rational(self) / Rational(right))
173
174    def __invert__(self):
175        return self.parent()(~Rational(self))
176
177    def __pow__(self, n):
178        if isinstance(n, InfinityElement):
179            if isinstance(n, PlusInfinityElement):
180                if self > 1:
181                    return self.parent().gen(1)
182                elif self == 1:
183                    return self
184                elif self > 0:
185                    return self.parent()(0)
186                elif self == 0:
187                    raise SignError, "0^infinity not defined"
188                elif self > -1:
189                    return self.parent()(0)
190                else:
191                    raise SignError, "negative^infinity not defined"
192            elif isinstance(n, MinusInfinityElement):
193                if self > 1:
194                    return self.parent()(0)
195                elif self == 1:
196                    return self
197                elif self > 0:
198                    return self.parent().gen(1)
199                elif self >= -1:
200                    raise SignError, "x^(-infinity) not defined for -1 <= x <= 0"
201                else:
202                    return self.parent()(0)
203            else:
204                raise TypeError, "cannot raise n to an unsigned infinite power."
205        return self.parent()(Rational(self)**n)
206
207    def __abs__(self):
208        return self.parent()(Rational(self).__abs__())
209
210    def numerator(self):
211        """
212        Returns the numerator of self as an extended integer.  If you want an actual integer, use numer instead.
213        """
214        return ExtendedIntegerRing(Rational(self).numerator())
215
216    def denominator(self):
217        """
218        Returns the denominator of self as an extended integer.  If you want an actual integer, use denom instead.
219        """
220        return ExtendedIntegerRing(Rational(self).denominator())
221
222    def floor(self):
223        return ExtendedIntegerRing(Rational(self).floor())
224
225    def ceil(self):
226        return ExtendedIntegerRing(Rational(self).ceil())
227
228    def __lshift__(self, n):
229        return self.parent()(Rational(self).__lshift__(n))
230
231    def __rshift__(self, n):
232        return self.parent()(Rational(self).__rshift__(n))
233
234
235class RationalPlusInfinity(_uniq1, PlusInfinityElement):
236    def __init__(self):
237        PlusInfinityElement.__init__(self, ExtendedRationalField)
238
239    def __cmp__(self, other):
240        if isinstance(other, RationalPlusInfinity):
241            return 0
242        return 1
243
244    def __repr__(self):
245        return "+Infinity"
246
247    def _latex_(self):
248        return "+\\infty"
249
250    def _add_(self, other):
251        if isinstance(other, RationalMinusInfinity):
252            raise SignError, "cannot add infinity to minus infinity"
253        return self
254
255    def _mul_(self, other):
256        if other < 0:
257            return -self
258        if other > 0:
259            return self
260        raise TypeError, "cannot multiply infinity by zero"
261
262    def _sub_(self, other):
263        if isinstance(other, RationalPlusInfinity):
264            raise SignError, "cannot add infinity to minus infinity"
265        return self
266
267    def _div_(self, other):
268        return self * other.__invert__()
269
270    def _neg_(self):
271        return self.parent().gen(2)
272
273    def __invert__(self):
274        return ExtendedRational(0)
275
276    def __abs__(self):
277        return self
278
279    def __pow__(self, right):
280        if not isinstance(right, (int, long, Integer, Rational, PlusInfinityElement, MinusInfinityElement)):
281            raise TypeError, "cannot exponentiate"
282        if right < 0:
283            return ExtendedRational(0)
284        elif right > 0:
285            return self
286        else:
287            raise SignError, "Cannot raise infinity to the zeroth power"
288
289    def lcm(self, x):
290        """
291        Return the least common multiple of oo and x, which
292        is by definition oo unless x is 0.
293
294        EXAMPLES:
295            sage: oo = InfinityRing.gen(0)
296            sage: oo.lcm(0)
297            0
298            sage: oo.lcm(oo)
299            +Infinity
300            sage: oo.lcm(10)
301            +Infinity
302        """
303        if x == 0:
304            return x
305        else:
306            return self
307
308    def sqrt(self):
309        return self
310
311    def square_root(self):
312        return self
313
314    def nth_root(self, n):
315        return self
316
317    def floor(self):
318        return IntegerPlusInfinity()
319
320    def ceil(self):
321        return IntegerPlusInfinity()
322
323    def numerator(self):
324        return IntegerPlusInfinity()
325
326    def denominator(self):
327        return ExtendedIntegerRing(1)
328
329class RationalMinusInfinity(_uniq2, MinusInfinityElement):
330    def __init__(self):
331        InfinityElement.__init__(self, ExtendedRationalField)
332
333    def __cmp__(self, other):
334        if isinstance(other, RationalMinusInfinity):
335            return 0
336        return -1
337
338    def _repr_(self):
339        return "-Infinity"
340
341    def _latex_(self):
342        return "-\\infty"
343
344    def _add_(self, other):
345        if isinstance(other, RationalPlusInfinity):
346            raise SignError, "cannot add infinity to minus infinity"
347        return self
348
349    def _mul_(self, other):
350        if other < 0:
351            return -self
352        if other > 0:
353            return self
354        raise SignError, "cannot multiply infinity by zero"
355
356    def _sub_(self, other):
357        if isinstance(other, RationalMinusInfinity):
358            raise SignError, "cannot add infinity to minus infinity"
359        return self
360
361    def _div_(self, other):
362        return self * other.__invert__()
363
364    def _neg_(self):
365        return self.parent().gen(1)
366
367    def __invert__(self):
368        return ExtendedRational(0)
369
370    def __abs__(self):
371        return self.parent().gen(1)
372
373    def __pow__(self, right):
374        if isinstance(right, Rational):
375            if right.denominator() % 2 == 0:
376                raise SignError, "Cannot take an even root of negative infinity"
377        elif not isinstance(right, (int, long, Integer, PlusInfinityElement, MinusInfinityElement)):
378            raise TypeError, "cannot exponentiate"
379        if right < 0:
380            return ExtendedRational(0)
381        elif right > 0:
382            return self
383        else:
384            raise SignError, "Cannot raise negative infinity to the zeroth power"
385
386    def lcm(self, x):
387        """
388        Return the least common multiple of -oo and x, which
389        is by definition oo unless x is 0.
390
391        EXAMPLES:
392            sage: moo = ExtendedRationalField.gen(2)
393            sage: moo.lcm(0)
394            0
395            sage: moo.lcm(oo)
396            +Infinity
397            sage: moo.lcm(10)
398            +Infinity
399        """
400        if x == 0:
401            return x
402        else:
403            return -self
404
405    def sqrt(self):
406        raise SignError, "cannot take square root of negative infinity"
407
408    def square_root(self):
409        raise SignError, "cannot take square root of negative infinity"
410   
411    def nth_root(self, n):
412        if n % 2 == 0:
413            raise SignError, "cannot take an even root of negative infinity"
414        return self
415
416    def floor(self):
417        return IntegerMinusInfinity()
418
419    def ceil(self):
420        return IntegerMinusInfinity()
421
422    def numerator(self):
423        return IntegerMinusInfinity()
424
425    def denominator(self):
426        return ExtendedIntegerRing(1)
Note: See TracBrowser for help on using the repository browser.