Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/rings/infinity.py
8817 views
1
r"""
2
Infinity Rings
3
4
The unsigned infinity "ring" is the set of two elements
5
6
1. infinity
7
8
2. A number less than infinity
9
10
The rules for arithmetic are that the unsigned infinity ring does
11
not canonically coerce to any other ring, and all other rings
12
canonically coerce to the unsigned infinity ring, sending all
13
elements to the single element "a number less than infinity" of the
14
unsigned infinity ring. Arithmetic and comparisons then take place
15
in the unsigned infinity ring, where all arithmetic operations that
16
are well-defined are defined.
17
18
The infinity "ring" is the set of five elements
19
20
1. plus infinity
21
22
2. a positive finite element
23
24
3. zero
25
26
4. a negative finite element
27
28
5. negative infinity
29
30
The infinity ring coerces to the unsigned infinity ring, sending
31
the infinite elements to infinity and the non-infinite elements to
32
"a number less than infinity." Any ordered ring coerces to the
33
infinity ring in the obvious way.
34
35
.. NOTE::
36
37
The shorthand ``oo`` is predefined in Sage to be the same as
38
``+Infinity`` in the infinity ring. It is considered equal to, but not
39
the same as ``Infinity`` in the
40
:class:`UnsignedInfinityRing<UnsignedInfinityRing_class>`.
41
42
EXAMPLES:
43
44
We fetch the unsigned infinity ring and create some elements::
45
46
sage: P = UnsignedInfinityRing; P
47
The Unsigned Infinity Ring
48
sage: P(5)
49
A number less than infinity
50
sage: P.ngens()
51
1
52
sage: unsigned_oo = P.0; unsigned_oo
53
Infinity
54
55
We compare finite numbers with infinity::
56
57
sage: 5 < unsigned_oo
58
True
59
sage: 5 > unsigned_oo
60
False
61
sage: unsigned_oo < 5
62
False
63
sage: unsigned_oo > 5
64
True
65
66
Demonstrating the shorthand ``oo`` versus ``Infinity``::
67
68
sage: oo
69
+Infinity
70
sage: oo is InfinityRing.0
71
True
72
sage: oo is UnsignedInfinityRing.0
73
False
74
sage: oo == UnsignedInfinityRing.0
75
True
76
77
We do arithmetic::
78
79
sage: unsigned_oo + 5
80
Infinity
81
82
We make ``1 / unsigned_oo`` return the integer 0 so that arithmetic of
83
the following type works::
84
85
sage: (1/unsigned_oo) + 2
86
2
87
sage: 32/5 - (2.439/unsigned_oo)
88
32/5
89
90
Note that many operations are not defined, since the result is not
91
well-defined::
92
93
sage: unsigned_oo/0
94
Traceback (most recent call last):
95
...
96
ValueError: unsigned oo times smaller number not defined
97
98
What happened above is that 0 is canonically coerced to "a number
99
less than infinity" in the unsigned infinity ring, and the quotient
100
is then not well-defined.
101
102
::
103
104
sage: 0/unsigned_oo
105
0
106
sage: unsigned_oo * 0
107
Traceback (most recent call last):
108
...
109
ValueError: unsigned oo times smaller number not defined
110
sage: unsigned_oo/unsigned_oo
111
Traceback (most recent call last):
112
...
113
ValueError: unsigned oo times smaller number not defined
114
115
In the infinity ring, we can negate infinity, multiply positive
116
numbers by infinity, etc.
117
118
::
119
120
sage: P = InfinityRing; P
121
The Infinity Ring
122
sage: P(5)
123
A positive finite number
124
125
The symbol ``oo`` is predefined as a shorthand for ``+Infinity``::
126
127
sage: oo
128
+Infinity
129
130
We compare finite and infinite elements::
131
132
sage: 5 < oo
133
True
134
sage: P(-5) < P(5)
135
True
136
sage: P(2) < P(3)
137
False
138
sage: -oo < oo
139
True
140
141
We can do more arithmetic than in the unsigned infinity ring::
142
143
sage: 2 * oo
144
+Infinity
145
sage: -2 * oo
146
-Infinity
147
sage: 1 - oo
148
-Infinity
149
sage: 1 / oo
150
0
151
sage: -1 / oo
152
0
153
154
We make ``1 / oo`` and ``1 / -oo`` return the integer 0 instead of the
155
infinity ring Zero so that arithmetic of the following type works::
156
157
sage: (1/oo) + 2
158
2
159
sage: 32/5 - (2.439/-oo)
160
32/5
161
162
If we try to subtract infinities or multiply infinity by zero we
163
still get an error::
164
165
sage: oo - oo
166
Traceback (most recent call last):
167
...
168
SignError: cannot add infinity to minus infinity
169
sage: 0 * oo
170
Traceback (most recent call last):
171
...
172
SignError: cannot multiply infinity by zero
173
sage: P(2) + P(-3)
174
Traceback (most recent call last):
175
...
176
SignError: cannot add positive finite value to negative finite value
177
178
TESTS::
179
180
sage: P = InfinityRing
181
sage: P == loads(dumps(P))
182
True
183
184
::
185
186
sage: P(2) == loads(dumps(P(2)))
187
True
188
189
The following is assumed in a lot of code (i.e., "is" is used for
190
testing whether something is infinity), so make sure it is satisfied::
191
192
sage: loads(dumps(infinity)) is infinity
193
True
194
"""
195
196
from sage.rings.ring_element import RingElement
197
from sage.rings.ring import Ring
198
from sage.structure.element import RingElement, InfinityElement, PlusInfinityElement, MinusInfinityElement
199
from sage.structure.parent_gens import ParentWithGens
200
#import sage.rings.real_double
201
#import sage.rings.real_mpfr
202
import sage.rings.integer
203
import sage.rings.rational
204
205
from sage.rings.integer_ring import ZZ
206
207
_obj = {}
208
class _uniq(object):
209
def __new__(cls, *args):
210
"""
211
This ensures uniqueness of these objects.
212
213
EXAMPLE::
214
215
sage: sage.rings.infinity.UnsignedInfinityRing_class() is sage.rings.infinity.UnsignedInfinityRing_class()
216
True
217
"""
218
if _obj.has_key(cls):
219
return _obj[cls]
220
_obj[cls] = O = cls.__bases__[-1].__new__(cls, *args)
221
return O
222
223
class AnInfinity:
224
225
def _repr_(self):
226
"""
227
Return a string representation of ``self``.
228
229
TESTS::
230
231
sage: [x._repr_() for x in [unsigned_infinity, oo, -oo]]
232
['Infinity', '+Infinity', '-Infinity']
233
"""
234
return self._sign_char + "Infinity"
235
236
def _giac_init_(self):
237
"""
238
TESTS::
239
240
sage: [x._giac_init_() for x in [unsigned_infinity, oo, -oo]]
241
['infinity', '+infinity', '-infinity']
242
"""
243
return self._sign_char + "infinity"
244
245
def _maxima_init_(self):
246
"""
247
TESTS::
248
249
sage: maxima(-oo)
250
minf
251
sage: [x._maxima_init_() for x in [unsigned_infinity, oo, -oo]]
252
['inf', 'inf', 'minf']
253
"""
254
if self._sign < 0:
255
return 'minf'
256
else:
257
return 'inf'
258
259
def _pari_(self):
260
"""
261
Convert ``self`` to a Pari object.
262
263
This always raises an exception since Pari does not have
264
infinities.
265
266
TESTS::
267
268
sage: pari(-oo) # indirect doctest
269
Traceback (most recent call last):
270
...
271
TypeError: cannot convert infinity to Pari
272
sage: pari(oo)
273
Traceback (most recent call last):
274
...
275
TypeError: cannot convert infinity to Pari
276
"""
277
raise TypeError, 'cannot convert infinity to Pari'
278
279
def _latex_(self):
280
r"""
281
Return a latex representation of ``self``.
282
283
EXAMPLES::
284
285
sage: latex(oo) # indirect doctest
286
+\infty
287
sage: [x._latex_() for x in [unsigned_infinity, oo, -oo]]
288
['\\infty', '+\\infty', '-\\infty']
289
"""
290
return self._sign_char + "\\infty"
291
292
def __cmp__(self, other):
293
"""
294
Compare ``self`` to ``other``.
295
296
EXAMPLES::
297
298
sage: oo == oo
299
True
300
sage: oo < oo
301
False
302
sage: -oo < oo
303
True
304
sage: -oo < 3 < oo
305
True
306
307
sage: unsigned_infinity == 3
308
False
309
sage: unsigned_infinity == unsigned_infinity
310
True
311
sage: unsigned_infinity == oo
312
True
313
"""
314
if isinstance(other, AnInfinity):
315
return cmp(self._sign, other._sign)
316
elif self._sign:
317
return self._sign
318
else:
319
return 1
320
321
def __abs__(self):
322
"""
323
EXAMPLES::
324
325
sage: [abs(x) for x in [UnsignedInfinityRing.gen(), oo, -oo]]
326
[Infinity, +Infinity, +Infinity]
327
"""
328
return -self if self._sign < 0 else self
329
330
def _add_(self, other):
331
"""
332
Add ``self`` to ``other``.
333
334
EXAMPLES::
335
336
sage: -oo + -oo # indirect doctest
337
-Infinity
338
sage: -oo + 3
339
-Infinity
340
sage: oo + -100
341
+Infinity
342
sage: oo + -oo
343
Traceback (most recent call last):
344
...
345
SignError: cannot add infinity to minus infinity
346
347
sage: unsigned_infinity = UnsignedInfinityRing.gen()
348
sage: unsigned_infinity + unsigned_infinity
349
Infinity
350
sage: unsigned_infinity + 88/3
351
Infinity
352
"""
353
if isinstance(other, AnInfinity):
354
if self._sign != other._sign:
355
raise SignError, "cannot add infinity to minus infinity"
356
return self
357
358
def _sub_(self, other):
359
"""
360
EXAMPLES::
361
362
sage: -oo - oo # indirect doctest
363
-Infinity
364
sage: oo - -oo
365
+Infinity
366
sage: oo - 4
367
+Infinity
368
sage: -oo - 1
369
-Infinity
370
sage: oo - oo
371
Traceback (most recent call last):
372
...
373
SignError: cannot add infinity to minus infinity
374
sage: unsigned_infinity - 4
375
Infinity
376
sage: unsigned_infinity - unsigned_infinity
377
Traceback (most recent call last):
378
...
379
ValueError: oo - oo not defined
380
"""
381
if isinstance(other, AnInfinity):
382
if self._sign == 0:
383
raise ValueError, "oo - oo not defined"
384
elif self._sign == other._sign:
385
raise SignError, "cannot add infinity to minus infinity"
386
return self
387
388
def _mul_(self, other):
389
"""
390
EXAMPLES::
391
392
sage: oo * 19 # indirect doctest
393
+Infinity
394
sage: oo * oo
395
+Infinity
396
sage: -oo * oo
397
-Infinity
398
sage: -oo * 4
399
-Infinity
400
sage: -oo * -2/3
401
+Infinity
402
sage: -oo * 0
403
Traceback (most recent call last):
404
...
405
SignError: cannot multiply infinity by zero
406
"""
407
if other < 0:
408
return -self
409
if other > 0:
410
return self
411
raise SignError, "cannot multiply infinity by zero"
412
413
def _div_(self, other):
414
"""
415
EXAMPLES::
416
417
sage: 1.5 / oo # indirect doctest
418
0
419
sage: oo / -4
420
-Infinity
421
sage: oo / oo
422
Traceback (most recent call last):
423
...
424
SignError: cannot multiply infinity by zero
425
"""
426
return self * ~other
427
428
def __float__(self):
429
r"""
430
Generate a floating-point infinity. The printing of
431
floating-point infinity varies across platforms.
432
433
EXAMPLES::
434
435
sage: RDF(infinity)
436
+infinity
437
sage: float(infinity) # random
438
+infinity
439
sage: CDF(infinity)
440
+infinity
441
sage: infinity.__float__() # random
442
+infinity
443
444
sage: RDF(-infinity)
445
-infinity
446
sage: float(-infinity) # random
447
-inf
448
sage: CDF(-infinity)
449
-infinity
450
sage: (-infinity).__float__() # random
451
-inf
452
453
"""
454
# Evidently there is no standard way to generate an infinity
455
# in Python (before Python 2.6).
456
from sage.rings.all import RR
457
return float(RR(self))
458
459
def lcm(self, x):
460
"""
461
Return the least common multiple of ``oo`` and ``x``, which
462
is by definition oo unless ``x`` is 0.
463
464
EXAMPLES::
465
466
sage: oo.lcm(0)
467
0
468
sage: oo.lcm(oo)
469
+Infinity
470
sage: oo.lcm(-oo)
471
+Infinity
472
sage: oo.lcm(10)
473
+Infinity
474
sage: (-oo).lcm(10)
475
+Infinity
476
"""
477
if x == 0:
478
return x
479
else:
480
return abs(self)
481
482
483
class UnsignedInfinityRing_class(_uniq, Ring):
484
485
def __init__(self):
486
"""
487
Initialize ``self``.
488
489
TESTS::
490
491
sage: sage.rings.infinity.UnsignedInfinityRing_class() is sage.rings.infinity.UnsignedInfinityRing_class() is UnsignedInfinityRing
492
True
493
"""
494
ParentWithGens.__init__(self, self, names=('oo',), normalize=False)
495
496
def ngens(self):
497
"""
498
The unsigned infinity ring has one "generator."
499
500
EXAMPLES::
501
502
sage: UnsignedInfinityRing.ngens()
503
1
504
sage: len(UnsignedInfinityRing.gens())
505
1
506
"""
507
return 1
508
509
def fraction_field(self):
510
"""
511
The unsigned infinity ring isn't an integral domain.
512
513
EXAMPLES::
514
515
sage: UnsignedInfinityRing.fraction_field()
516
Traceback (most recent call last):
517
...
518
TypeError: infinity 'ring' has no fraction field
519
"""
520
raise TypeError, "infinity 'ring' has no fraction field"
521
522
def gen(self, n=0):
523
"""
524
The "generator" of ``self`` is the infinity object.
525
526
EXAMPLES::
527
528
sage: UnsignedInfinityRing.gen()
529
Infinity
530
sage: UnsignedInfinityRing.gen(1)
531
Traceback (most recent call last):
532
...
533
IndexError: UnsignedInfinityRing only has one generator
534
"""
535
if n == 0:
536
try:
537
return self._gen
538
except AttributeError:
539
self._gen = UnsignedInfinity()
540
return self._gen
541
else:
542
raise IndexError, "UnsignedInfinityRing only has one generator"
543
544
def gens(self):
545
"""
546
The "generator" of ``self`` is the infinity object.
547
548
EXAMPLES::
549
550
sage: UnsignedInfinityRing.gens()
551
[Infinity]
552
"""
553
return [self.gen()]
554
555
def less_than_infinity(self):
556
"""
557
This is the element that represents a finite value.
558
559
EXAMPLES::
560
561
sage: UnsignedInfinityRing.less_than_infinity()
562
A number less than infinity
563
sage: UnsignedInfinityRing(5) is UnsignedInfinityRing.less_than_infinity()
564
True
565
"""
566
try:
567
return self._less_than_infinity
568
except AttributeError:
569
self._less_than_infinity = LessThanInfinity(self)
570
return self._less_than_infinity
571
572
def _repr_(self):
573
"""
574
Return a string representation of ``self``.
575
576
TESTS::
577
578
sage: UnsignedInfinityRing._repr_()
579
'The Unsigned Infinity Ring'
580
"""
581
return "The Unsigned Infinity Ring"
582
583
def __cmp__(self, right):
584
"""
585
Compare ``self`` to ``right``.
586
587
TESTS::
588
589
sage: infinity == UnsignedInfinityRing.gen()
590
True
591
sage: UnsignedInfinityRing(3) == UnsignedInfinityRing(-19.5)
592
True
593
"""
594
if isinstance(right, UnsignedInfinityRing_class):
595
return 0
596
return cmp(type(self), type(right))
597
598
def _element_constructor_(self, x):
599
"""
600
TESTS::
601
602
sage: UnsignedInfinityRing(2) # indirect doctest
603
A number less than infinity
604
sage: UnsignedInfinityRing(I)
605
A number less than infinity
606
sage: UnsignedInfinityRing(infinity)
607
Infinity
608
sage: UnsignedInfinityRing(float('+inf'))
609
Infinity
610
"""
611
if isinstance(x, InfinityElement):
612
if x.parent() is self:
613
return x
614
else:
615
return self.gen()
616
elif isinstance(x, RingElement) or isinstance(x, (int,long)):
617
return self.less_than_infinity()
618
elif isinstance(x, (float, complex)):
619
if x == float('+inf') or x == float('-inf'):
620
return self.gen()
621
return self.less_than_infinity()
622
else:
623
raise TypeError
624
625
def _coerce_map_from_(self, R):
626
"""
627
EXAMPLES::
628
629
sage: UnsignedInfinityRing.has_coerce_map_from(int) # indirect doctest
630
True
631
sage: UnsignedInfinityRing.has_coerce_map_from(CC)
632
True
633
sage: UnsignedInfinityRing.has_coerce_map_from(QuadraticField(-163, 'a'))
634
True
635
sage: UnsignedInfinityRing.has_coerce_map_from(QQ^3)
636
False
637
sage: UnsignedInfinityRing.has_coerce_map_from(SymmetricGroup(13))
638
False
639
"""
640
return isinstance(R, Ring) or R in (int, long, float, complex)
641
642
UnsignedInfinityRing = UnsignedInfinityRing_class()
643
644
class LessThanInfinity(_uniq, RingElement):
645
def __init__(self, parent=UnsignedInfinityRing):
646
"""
647
Initialize ``self``.
648
649
EXAMPLES::
650
651
sage: sage.rings.infinity.LessThanInfinity() is UnsignedInfinityRing(5)
652
True
653
"""
654
RingElement.__init__(self, parent)
655
656
def _repr_(self):
657
"""
658
Return a string representation of ``self``.
659
660
EXAMPLES::
661
662
sage: UnsignedInfinityRing(5)._repr_()
663
'A number less than infinity'
664
"""
665
return "A number less than infinity"
666
667
def _latex_(self):
668
"""
669
Return a latex representation of ``self``.
670
671
EXAMPLES::
672
673
sage: UnsignedInfinityRing(5)._latex_()
674
'(<\\infty)'
675
"""
676
return "(<\\infty)"
677
678
def _add_(self, other):
679
"""
680
EXAMPLES::
681
682
sage: UnsignedInfinityRing(5) + UnsignedInfinityRing(-3) # indirect doctest
683
A number less than infinity
684
sage: UnsignedInfinityRing(5) + unsigned_infinity
685
Infinity
686
"""
687
if isinstance(other, UnsignedInfinity):
688
return other
689
return self
690
691
def _sub_(self, other):
692
"""
693
EXAMPLES::
694
695
sage: UnsignedInfinityRing(5) - UnsignedInfinityRing(-3) # indirect doctest
696
A number less than infinity
697
sage: UnsignedInfinityRing(5) - unsigned_infinity
698
Infinity
699
"""
700
if isinstance(other, UnsignedInfinity):
701
return other
702
return self
703
704
def _mul_(self, other):
705
"""
706
EXAMPLES::
707
708
sage: UnsignedInfinityRing(4) * UnsignedInfinityRing(-3) # indirect doctest
709
A number less than infinity
710
sage: 5 * unsigned_infinity
711
Traceback (most recent call last):
712
...
713
ValueError: oo times number < oo not defined
714
sage: unsigned_infinity * unsigned_infinity
715
Infinity
716
"""
717
if isinstance(other, UnsignedInfinity):
718
raise ValueError, "oo times number < oo not defined"
719
return self
720
721
def _div_(self, other):
722
"""
723
Can't eliminate possibility of zero division....
724
725
EXAMPLES::
726
727
sage: UnsignedInfinityRing(2) / UnsignedInfinityRing(5) # indirect doctest
728
Traceback (most recent call last):
729
...
730
ValueError: quotient of number < oo by number < oo not defined
731
sage: 1 / unsigned_infinity
732
0
733
"""
734
if isinstance(other, UnsignedInfinity):
735
return ZZ(0)
736
raise ValueError, "quotient of number < oo by number < oo not defined"
737
738
def __cmp__(self, other):
739
"""
740
Compare ``self`` to ``other``.
741
742
EXAMPLES::
743
744
sage: 1 == unsigned_infinity
745
False
746
"""
747
if isinstance(other, UnsignedInfinity):
748
return -1
749
return 0
750
751
752
class UnsignedInfinity(_uniq, AnInfinity, InfinityElement):
753
754
_sign = 0
755
_sign_char = ''
756
757
def __init__(self):
758
"""
759
Initialize ``self``.
760
761
TESTS::
762
763
sage: sage.rings.infinity.UnsignedInfinity() is sage.rings.infinity.UnsignedInfinity() is unsigned_infinity
764
True
765
"""
766
InfinityElement.__init__(self, UnsignedInfinityRing)
767
768
def _mul_(self, other):
769
"""
770
Can't rule out an attempt at multiplication by 0.
771
772
EXAMPLES::
773
774
sage: unsigned_infinity * unsigned_infinity # indirect doctest
775
Infinity
776
sage: unsigned_infinity * 0
777
Traceback (most recent call last):
778
...
779
ValueError: unsigned oo times smaller number not defined
780
sage: unsigned_infinity * 3
781
Traceback (most recent call last):
782
...
783
ValueError: unsigned oo times smaller number not defined
784
"""
785
if isinstance(other, UnsignedInfinity):
786
return self
787
raise ValueError, "unsigned oo times smaller number not defined"
788
789
790
unsigned_infinity = UnsignedInfinityRing.gen(0)
791
less_than_infinity = UnsignedInfinityRing.less_than_infinity()
792
793
def is_Infinite(x):
794
"""
795
This is a type check for infinity elements.
796
797
EXAMPLES::
798
799
sage: sage.rings.infinity.is_Infinite(oo)
800
True
801
sage: sage.rings.infinity.is_Infinite(-oo)
802
True
803
sage: sage.rings.infinity.is_Infinite(unsigned_infinity)
804
True
805
sage: sage.rings.infinity.is_Infinite(3)
806
False
807
sage: sage.rings.infinity.is_Infinite(RR(infinity))
808
False
809
sage: sage.rings.infinity.is_Infinite(ZZ)
810
False
811
"""
812
return isinstance(x, InfinityElement)
813
814
class SignError(ArithmeticError):
815
"""
816
Sign error exception.
817
"""
818
pass
819
820
class InfinityRing_class(_uniq, Ring):
821
def __init__(self):
822
"""
823
Initialize ``self``.
824
825
TEST::
826
827
sage: sage.rings.infinity.InfinityRing_class() is sage.rings.infinity.InfinityRing_class() is InfinityRing
828
True
829
"""
830
ParentWithGens.__init__(self, self, names=('oo',), normalize=False)
831
832
def fraction_field(self):
833
"""
834
This isn't really a ring, let alone an integral domain.
835
836
TEST::
837
838
sage: InfinityRing.fraction_field()
839
Traceback (most recent call last):
840
...
841
TypeError: infinity 'ring' has no fraction field
842
"""
843
raise TypeError, "infinity 'ring' has no fraction field"
844
845
def ngens(self):
846
"""
847
The two generators are plus and minus infinity.
848
849
EXAMPLES::
850
851
sage: InfinityRing.ngens()
852
2
853
sage: len(InfinityRing.gens())
854
2
855
"""
856
return 2
857
858
def gen(self, n=0):
859
"""
860
The two generators are plus and minus infinity.
861
862
EXAMPLES::
863
864
sage: InfinityRing.gen(0)
865
+Infinity
866
sage: InfinityRing.gen(1)
867
-Infinity
868
sage: InfinityRing.gen(2)
869
Traceback (most recent call last):
870
...
871
IndexError: n must be 0 or 1
872
"""
873
try:
874
if n == 0:
875
return self._gen0
876
elif n == 1:
877
return self._gen1
878
else:
879
raise IndexError, "n must be 0 or 1"
880
except AttributeError:
881
if n == 0:
882
self._gen0 = PlusInfinity()
883
return self._gen0
884
elif n == 1:
885
self._gen1 = MinusInfinity()
886
return self._gen1
887
888
def gens(self):
889
"""
890
The two generators are plus and minus infinity.
891
892
EXAMPLES::
893
894
sage: InfinityRing.gens()
895
[+Infinity, -Infinity]
896
"""
897
return [self.gen(0), self.gen(1)]
898
899
def _repr_(self):
900
"""
901
Return a string representation of ``self``.
902
903
TEST::
904
905
sage: InfinityRing._repr_()
906
'The Infinity Ring'
907
"""
908
return "The Infinity Ring"
909
910
def __cmp__(self, right):
911
"""
912
Compare ``self`` to ``right``.
913
914
TESTS::
915
916
sage: InfinityRing == InfinityRing
917
True
918
sage: InfinityRing == UnsignedInfinityRing
919
False
920
"""
921
if isinstance(right, InfinityRing_class):
922
return 0
923
return cmp(type(self), type(right))
924
925
def _element_constructor_(self, x):
926
"""
927
TESTS::
928
929
sage: InfinityRing(-oo) # indirect doctest
930
-Infinity
931
sage: InfinityRing(3)
932
A positive finite number
933
sage: InfinityRing(-1.5)
934
A negative finite number
935
sage: [InfinityRing(a) for a in [-2..2]]
936
[A negative finite number, A negative finite number, Zero, A positive finite number, A positive finite number]
937
sage: K.<a> = QuadraticField(3)
938
sage: InfinityRing(a)
939
A positive finite number
940
sage: InfinityRing(a - 2)
941
A negative finite number
942
943
Check that :trac:`14045` is fixed::
944
945
sage: InfinityRing(float('+inf'))
946
+Infinity
947
sage: InfinityRing(float('-inf'))
948
-Infinity
949
sage: oo > float('+inf')
950
False
951
sage: oo == float('+inf')
952
True
953
"""
954
if isinstance(x, PlusInfinityElement):
955
return self.gen(0)
956
elif isinstance(x, MinusInfinityElement):
957
return self.gen(1)
958
elif isinstance(x, InfinityElement):
959
return self.gen(0)
960
elif (isinstance(x, (sage.rings.integer.Integer,
961
sage.rings.rational.Rational,
962
sage.rings.real_double.RealDoubleElement,
963
sage.rings.real_mpfr.RealNumber))
964
or isinstance(x, (int,long,float))
965
or sage.rings.real_mpfr.RealField(sage.rings.real_mpfr.mpfr_prec_min())(x)):
966
if x == float('+inf'):
967
return self.gen(0)
968
elif x == float('-inf'):
969
return self.gen(1)
970
elif x < 0:
971
return FiniteNumber(self, -1)
972
elif x > 0:
973
return FiniteNumber(self, 1)
974
elif x == 0:
975
return FiniteNumber(self, 0)
976
else:
977
raise TypeError
978
else:
979
raise TypeError
980
981
def _coerce_map_from_(self, R):
982
"""
983
There is a coercion from anything that has a coercion into the reals.
984
985
EXAMPLES::
986
987
sage: InfinityRing.has_coerce_map_from(int) # indirect doctest
988
True
989
sage: InfinityRing.has_coerce_map_from(AA)
990
True
991
sage: InfinityRing.has_coerce_map_from(RDF)
992
True
993
sage: InfinityRing.has_coerce_map_from(CC)
994
False
995
"""
996
return sage.rings.real_mpfr.RealField(sage.rings.real_mpfr.mpfr_prec_min()).has_coerce_map_from(R)
997
998
class FiniteNumber(RingElement):
999
def __init__(self, parent, x):
1000
"""
1001
Initialize ``self``.
1002
1003
TESTS::
1004
1005
sage: sage.rings.infinity.FiniteNumber(InfinityRing, 1)
1006
A positive finite number
1007
sage: sage.rings.infinity.FiniteNumber(InfinityRing, -1)
1008
A negative finite number
1009
sage: sage.rings.infinity.FiniteNumber(InfinityRing, 0)
1010
Zero
1011
"""
1012
RingElement.__init__(self, parent)
1013
self.value = x
1014
1015
def __cmp__(self, other):
1016
"""
1017
Compare ``self`` and ``other``.
1018
1019
EXAMPLES::
1020
1021
sage: P = InfinityRing
1022
sage: -oo < P(-5) < P(0) < P(1.5) < oo
1023
True
1024
sage: P(1) < P(100)
1025
False
1026
sage: P(-1) == P(-100)
1027
True
1028
"""
1029
if isinstance(other, PlusInfinity):
1030
return -1
1031
if isinstance(other, MinusInfinity):
1032
return 1
1033
return cmp(self.value, other.value)
1034
1035
def _add_(self, other):
1036
"""
1037
EXAMPLES::
1038
1039
sage: P = InfinityRing
1040
sage: 4 + oo # indirect doctest
1041
+Infinity
1042
sage: P(4) + P(2)
1043
A positive finite number
1044
sage: P(-1) + P(1)
1045
Traceback (most recent call last):
1046
...
1047
SignError: cannot add positive finite value to negative finite value
1048
"""
1049
if isinstance(other, InfinityElement):
1050
return other
1051
if self.value * other.value < 0:
1052
raise SignError, "cannot add positive finite value to negative finite value"
1053
return FiniteNumber(self.parent(), self.value)
1054
1055
def _mul_(self, other):
1056
"""
1057
EXAMPLES::
1058
1059
sage: P = InfinityRing
1060
sage: 0 * oo # indirect doctest
1061
Traceback (most recent call last):
1062
...
1063
SignError: cannot multiply infinity by zero
1064
sage: -1 * oo
1065
-Infinity
1066
sage: -2 * oo
1067
-Infinity
1068
sage: 3 * oo
1069
+Infinity
1070
sage: -oo * oo
1071
-Infinity
1072
sage: P(0) * 3
1073
0
1074
sage: P(-3) * P(2/3)
1075
A negative finite number
1076
"""
1077
if other.is_zero():
1078
if isinstance(self, InfinityElement):
1079
raise SignError, "cannot multiply infinity by zero"
1080
return ZZ(0)
1081
if self.value < 0:
1082
if isinstance(other, InfinityElement):
1083
return -other
1084
return FiniteNumber(self.parent(), self.value * other.value)
1085
if self.value > 0:
1086
if isinstance(other, InfinityElement):
1087
return other
1088
return FiniteNumber(self.parent(), self.value * other.value)
1089
if self.value == 0:
1090
if isinstance(other, InfinityElement):
1091
raise SignError, "cannot multiply infinity by zero"
1092
return ZZ(0)
1093
1094
def _div_(self, other):
1095
"""
1096
EXAMPLES::
1097
1098
sage: P = InfinityRing
1099
sage: 1 / oo # indirect doctest
1100
0
1101
sage: oo / 4
1102
+Infinity
1103
sage: oo / -4
1104
-Infinity
1105
sage: P(1) / P(-4)
1106
A negative finite number
1107
"""
1108
return self * ~other
1109
1110
def _sub_(self, other):
1111
"""
1112
EXAMPLES::
1113
1114
sage: P = InfinityRing
1115
sage: 4 - oo # indirect doctest
1116
-Infinity
1117
sage: 5 - -oo
1118
+Infinity
1119
sage: P(44) - P(4)
1120
Traceback (most recent call last):
1121
...
1122
SignError: cannot add positive finite value to negative finite value
1123
sage: P(44) - P(-1)
1124
A positive finite number
1125
"""
1126
return self._add_(-other)
1127
1128
def __invert__(self):
1129
"""
1130
EXAMPLES::
1131
1132
sage: P = InfinityRing
1133
sage: ~P(2)
1134
A positive finite number
1135
sage: ~P(-7)
1136
A negative finite number
1137
sage: ~P(0)
1138
Traceback (most recent call last):
1139
...
1140
ZeroDivisionError: Cannot divide by zero
1141
"""
1142
if self.value == 0:
1143
raise ZeroDivisionError, "Cannot divide by zero"
1144
return self
1145
1146
def _neg_(self):
1147
"""
1148
EXAMPLES::
1149
1150
sage: a = InfinityRing(5); a
1151
A positive finite number
1152
sage: -a # indirect doctest
1153
A negative finite number
1154
sage: -(-a) == a
1155
True
1156
sage: -InfinityRing(0)
1157
Zero
1158
"""
1159
return FiniteNumber(self.parent(), -self.value)
1160
1161
def _repr_(self):
1162
"""
1163
Return a string representation of ``self``.
1164
1165
EXAMPLES::
1166
1167
sage: InfinityRing(-2)._repr_()
1168
'A negative finite number'
1169
sage: InfinityRing(7)._repr_()
1170
'A positive finite number'
1171
sage: InfinityRing(0)._repr_()
1172
'Zero'
1173
"""
1174
if self.value < 0:
1175
return "A negative finite number"
1176
if self.value > 0:
1177
return "A positive finite number"
1178
return "Zero"
1179
1180
def _latex_(self):
1181
"""
1182
Return a latex representation of ``self``.
1183
1184
TESTS::
1185
1186
sage: a = InfinityRing(pi); a
1187
A positive finite number
1188
sage: a._latex_()
1189
'A positive finite number'
1190
sage: [latex(InfinityRing(a)) for a in [-2..2]]
1191
[A negative finite number, A negative finite number, Zero, A positive finite number, A positive finite number]
1192
"""
1193
return self._repr_()
1194
1195
def __abs__(self):
1196
"""
1197
EXAMPLES::
1198
1199
sage: abs(InfinityRing(-3))
1200
A positive finite number
1201
sage: abs(InfinityRing(3))
1202
A positive finite number
1203
sage: abs(InfinityRing(0))
1204
Zero
1205
"""
1206
if self.value == 0:
1207
return FiniteNumber(self.parent(), 0)
1208
return FiniteNumber(self.parent(), 1)
1209
1210
def sqrt(self):
1211
"""
1212
EXAMPLES::
1213
1214
sage: InfinityRing(7).sqrt()
1215
A positive finite number
1216
sage: InfinityRing(0).sqrt()
1217
Zero
1218
sage: InfinityRing(-.001).sqrt()
1219
Traceback (most recent call last):
1220
...
1221
SignError: cannot take square root of a negative number
1222
"""
1223
if self.value < 0:
1224
raise SignError, "cannot take square root of a negative number"
1225
return self
1226
1227
class MinusInfinity(_uniq, AnInfinity, MinusInfinityElement):
1228
1229
_sign = -1
1230
_sign_char = '-'
1231
1232
def __init__(self):
1233
"""
1234
Initialize ``self``.
1235
1236
TESTS::
1237
1238
sage: sage.rings.infinity.MinusInfinity() is sage.rings.infinity.MinusInfinity() is -oo
1239
True
1240
"""
1241
InfinityElement.__init__(self, InfinityRing)
1242
1243
def _neg_(self):
1244
"""
1245
EXAMPLES::
1246
1247
sage: -(-oo) # indirect doctest
1248
+Infinity
1249
"""
1250
return self.parent().gen(0)
1251
1252
def sqrt(self):
1253
"""
1254
EXAMPLES::
1255
1256
sage: (-oo).sqrt()
1257
Traceback (most recent call last):
1258
...
1259
SignError: cannot take square root of negative infinity
1260
"""
1261
raise SignError, "cannot take square root of negative infinity"
1262
1263
def _sympy_(self):
1264
"""
1265
Converts ``-oo`` to sympy ``-oo``.
1266
1267
Then you don't have to worry which ``oo`` you use, like in these
1268
examples:
1269
1270
EXAMPLES::
1271
1272
sage: import sympy
1273
sage: bool(-oo == -sympy.oo)
1274
True
1275
sage: bool(SR(-oo) == -sympy.oo)
1276
True
1277
sage: bool((-oo)._sympy_() == -sympy.oo)
1278
True
1279
1280
"""
1281
import sympy
1282
return -sympy.oo
1283
1284
1285
class PlusInfinity(_uniq, AnInfinity, PlusInfinityElement):
1286
1287
_sign = 1
1288
_sign_char = '+'
1289
1290
def __init__(self):
1291
"""
1292
Initialize ``self``.
1293
1294
TESTS::
1295
1296
sage: sage.rings.infinity.PlusInfinity() is sage.rings.infinity.PlusInfinity() is oo
1297
True
1298
"""
1299
InfinityElement.__init__(self, InfinityRing)
1300
1301
def _neg_(self):
1302
"""
1303
TESTS::
1304
1305
sage: -oo # indirect doctest
1306
-Infinity
1307
"""
1308
return self.parent().gen(1)
1309
1310
def sqrt(self):
1311
"""
1312
The square root of ``self``.
1313
1314
The square root of infinity is infinity.
1315
1316
EXAMPLES::
1317
1318
sage: oo.sqrt()
1319
+Infinity
1320
"""
1321
return self
1322
1323
def _sympy_(self):
1324
"""
1325
Converts ``oo`` to sympy ``oo``.
1326
1327
Then you don't have to worry which ``oo`` you use, like in these
1328
examples:
1329
1330
EXAMPLE::
1331
1332
sage: import sympy
1333
sage: bool(oo == sympy.oo) # indirect doctest
1334
True
1335
sage: bool(SR(oo) == sympy.oo)
1336
True
1337
"""
1338
import sympy
1339
return sympy.oo
1340
1341
InfinityRing = InfinityRing_class()
1342
infinity = InfinityRing.gen(0)
1343
Infinity = infinity
1344
minus_infinity = InfinityRing.gen(1)
1345
1346
1347