Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Signed and Unsigned Infinities
The unsigned infinity "ring" is the set of two elements
1. infinity
2. A number less than infinity
The rules for arithmetic are that the unsigned infinity ring does not canonically coerce to any other ring, and all other rings canonically coerce to the unsigned infinity ring, sending all elements to the single element "a number less than infinity" of the unsigned infinity ring. Arithmetic and comparisons then take place in the unsigned infinity ring, where all arithmetic operations that are well-defined are defined.
The infinity "ring" is the set of five elements
1. plus infinity
2. a positive finite element
3. zero
4. a negative finite element
5. negative infinity
The infinity ring coerces to the unsigned infinity ring, sending the infinite elements to infinity and the non-infinite elements to "a number less than infinity." Any ordered ring coerces to the infinity ring in the obvious way.
.. NOTE::
The shorthand ``oo`` is predefined in Sage to be the same as ``+Infinity`` in the infinity ring. It is considered equal to, but not the same as ``Infinity`` in the :class:`UnsignedInfinityRing<UnsignedInfinityRing_class>`.
EXAMPLES:
We fetch the unsigned infinity ring and create some elements::
sage: P = UnsignedInfinityRing; P The Unsigned Infinity Ring sage: P(5) A number less than infinity sage: P.ngens() 1 sage: unsigned_oo = P.0; unsigned_oo Infinity
We compare finite numbers with infinity::
sage: 5 < unsigned_oo True sage: 5 > unsigned_oo False sage: unsigned_oo < 5 False sage: unsigned_oo > 5 True
Demonstrating the shorthand ``oo`` versus ``Infinity``::
sage: oo +Infinity sage: oo is InfinityRing.0 True sage: oo is UnsignedInfinityRing.0 False sage: oo == UnsignedInfinityRing.0 True
We do arithmetic::
sage: unsigned_oo + 5 Infinity
We make ``1 / unsigned_oo`` return the integer 0 so that arithmetic of the following type works::
sage: (1/unsigned_oo) + 2 2 sage: 32/5 - (2.439/unsigned_oo) 32/5
Note that many operations are not defined, since the result is not well-defined::
sage: unsigned_oo/0 Traceback (most recent call last): ... ValueError: quotient of number < oo by number < oo not defined
What happened above is that 0 is canonically coerced to "A number less than infinity" in the unsigned infinity ring. Next, Sage tries to divide by multiplying with its inverse. Finally, this inverse is not well-defined.
::
sage: 0/unsigned_oo 0 sage: unsigned_oo * 0 Traceback (most recent call last): ... ValueError: unsigned oo times smaller number not defined sage: unsigned_oo/unsigned_oo Traceback (most recent call last): ... ValueError: unsigned oo times smaller number not defined
In the infinity ring, we can negate infinity, multiply positive numbers by infinity, etc.
::
sage: P = InfinityRing; P The Infinity Ring sage: P(5) A positive finite number
The symbol ``oo`` is predefined as a shorthand for ``+Infinity``::
sage: oo +Infinity
We compare finite and infinite elements::
sage: 5 < oo True sage: P(-5) < P(5) True sage: P(2) < P(3) False sage: -oo < oo True
We can do more arithmetic than in the unsigned infinity ring::
sage: 2 * oo +Infinity sage: -2 * oo -Infinity sage: 1 - oo -Infinity sage: 1 / oo 0 sage: -1 / oo 0
We make ``1 / oo`` and ``1 / -oo`` return the integer 0 instead of the infinity ring Zero so that arithmetic of the following type works::
sage: (1/oo) + 2 2 sage: 32/5 - (2.439/-oo) 32/5
If we try to subtract infinities or multiply infinity by zero we still get an error::
sage: oo - oo Traceback (most recent call last): ... SignError: cannot add infinity to minus infinity sage: 0 * oo Traceback (most recent call last): ... SignError: cannot multiply infinity by zero sage: P(2) + P(-3) Traceback (most recent call last): ... SignError: cannot add positive finite value to negative finite value
Signed infinity can also be represented by RR / RDF elements. But unsigned infinity cannot::
sage: oo in RR, oo in RDF (True, True) sage: unsigned_infinity in RR, unsigned_infinity in RDF (False, False)
TESTS::
sage: P = InfinityRing sage: P == loads(dumps(P)) True
::
sage: P(2) == loads(dumps(P(2))) True
The following is assumed in a lot of code (i.e., "is" is used for testing whether something is infinity), so make sure it is satisfied::
sage: loads(dumps(infinity)) is infinity True
We check that :trac:`17990` is fixed::
sage: m = Matrix([Infinity]) sage: m.rows() [(+Infinity)] """ #***************************************************************************** # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** # python3 from __future__ import division from six import integer_types
from sys import maxsize from sage.rings.ring import Ring from sage.structure.element import RingElement, InfinityElement from sage.structure.richcmp import rich_to_bool, richcmp from sage.structure.parent import Parent from sage.misc.fast_methods import Singleton import sage.rings.integer import sage.rings.rational
import sage.rings.integer_ring
_obj = {} class _uniq(object): def __new__(cls, *args): """ This ensures uniqueness of these objects.
EXAMPLES::
sage: sage.rings.infinity.UnsignedInfinityRing_class() is sage.rings.infinity.UnsignedInfinityRing_class() True """ _obj[cls] = O = cls.__bases__[-1].__new__(cls, *args) return O
class AnInfinity(object): """ TESTS::
sage: oo == oo True sage: oo < oo False sage: -oo < oo True sage: -oo < 3 < oo True
sage: unsigned_infinity == 3 False sage: unsigned_infinity == unsigned_infinity True sage: unsigned_infinity == oo True """
def _repr_(self): """ Return a string representation of ``self``.
TESTS::
sage: [x._repr_() for x in [unsigned_infinity, oo, -oo]] ['Infinity', '+Infinity', '-Infinity'] """
def _giac_init_(self): """ TESTS::
sage: [x._giac_init_() for x in [unsigned_infinity, oo, -oo]] ['infinity', '+infinity', '-infinity'] """
def _maxima_init_(self): """ TESTS::
sage: maxima(-oo) minf sage: [x._maxima_init_() for x in [unsigned_infinity, oo, -oo]] ['inf', 'inf', 'minf'] """ else:
def _fricas_init_(self): """ TESTS::
sage: fricas(-oo) # optional - fricas - infinity sage: [x._fricas_init_() for x in [unsigned_infinity, oo, -oo]] # optional - fricas ['%infinity', '%plusInfinity', '%minusInfinity'] sage: [fricas(x) for x in [unsigned_infinity, oo, -oo]] # optional - fricas [infinity, + infinity, - infinity] """ if self._sign_char == '': return r"%infinity" elif self._sign > 0: return r"%plusInfinity" else: return r"%minusInfinity"
def __pari__(self): """ Convert ``self`` to a Pari object.
EXAMPLES::
sage: pari(-oo) -oo sage: pari(oo) +oo """ # For some reason, it seems problematic to import sage.libs.all.pari, # so we call it directly. else:
def _latex_(self): r""" Return a latex representation of ``self``.
EXAMPLES::
sage: latex(oo) # indirect doctest +\infty sage: [x._latex_() for x in [unsigned_infinity, oo, -oo]] ['\\infty', '+\\infty', '-\\infty'] """
def __abs__(self): """ EXAMPLES::
sage: [abs(x) for x in [UnsignedInfinityRing.gen(), oo, -oo]] [Infinity, +Infinity, +Infinity] """
def _add_(self, other): """ Add ``self`` to ``other``.
EXAMPLES::
sage: -oo + -oo # indirect doctest -Infinity sage: -oo + 3 -Infinity sage: oo + -100 +Infinity sage: oo + -oo Traceback (most recent call last): ... SignError: cannot add infinity to minus infinity
sage: unsigned_infinity = UnsignedInfinityRing.gen() sage: unsigned_infinity + unsigned_infinity Traceback (most recent call last): ... SignError: cannot add unsigned infinities sage: unsigned_infinity + oo*i Traceback (most recent call last): ... SignError: cannot add unsigned infinities sage: unsigned_infinity + 88/3 Infinity """ # just like oo - oo is undefined
def _sub_(self, other): """ EXAMPLES::
sage: -oo - oo # indirect doctest -Infinity sage: oo - -oo +Infinity sage: oo - 4 +Infinity sage: -oo - 1 -Infinity sage: oo - oo Traceback (most recent call last): ... SignError: cannot add infinity to minus infinity sage: unsigned_infinity - 4 Infinity sage: unsigned_infinity - unsigned_infinity Traceback (most recent call last): ... SignError: cannot subtract unsigned infinities sage: unsigned_infinity - oo*i Traceback (most recent call last): ... SignError: cannot subtract unsigned infinities """
def _mul_(self, other): """ EXAMPLES::
sage: oo * 19 # indirect doctest +Infinity sage: oo * oo +Infinity sage: -oo * oo -Infinity sage: -oo * 4 -Infinity sage: -oo * -2/3 +Infinity sage: -oo * 0 Traceback (most recent call last): ... SignError: cannot multiply infinity by zero """
def _div_(self, other): """ EXAMPLES::
sage: 1.5 / oo # indirect doctest 0 sage: oo / -4 -Infinity sage: oo / oo Traceback (most recent call last): ... SignError: cannot multiply infinity by zero
Check that :trac:`14857` is fixed::
sage: infinity / unsigned_infinity Traceback (most recent call last): ... ValueError: unsigned oo times smaller number not defined sage: SR(infinity) / unsigned_infinity Traceback (most recent call last): ... RuntimeError: indeterminate expression: 0 * infinity encountered. """
def __float__(self): r""" Generate a floating-point infinity. The printing of floating-point infinity varies across platforms.
EXAMPLES::
sage: RDF(infinity) +infinity sage: float(infinity) # random +infinity sage: CDF(infinity) +infinity sage: infinity.__float__() # random +infinity
sage: RDF(-infinity) -infinity sage: float(-infinity) # random -inf sage: CDF(-infinity) -infinity sage: (-infinity).__float__() # random -inf sage: float(unsigned_infinity) Traceback (most recent call last): ... ValueError: unsigned infinity cannot be represented in a float """
def lcm(self, x): """ Return the least common multiple of ``oo`` and ``x``, which is by definition oo unless ``x`` is 0.
EXAMPLES::
sage: oo.lcm(0) 0 sage: oo.lcm(oo) +Infinity sage: oo.lcm(-oo) +Infinity sage: oo.lcm(10) +Infinity sage: (-oo).lcm(10) +Infinity """ else:
def _sage_input_(self, sib, coerced): """ Produce an expression which will reproduce this value when evaluated.
TESTS::
sage: sage_input(-oo) -oo sage: sage_input(oo) oo sage: sage_input(unsigned_infinity) unsigned_infinity """ else:
class UnsignedInfinityRing_class(Singleton, Ring):
def __init__(self): """ Initialize ``self``.
TESTS::
sage: sage.rings.infinity.UnsignedInfinityRing_class() is sage.rings.infinity.UnsignedInfinityRing_class() is UnsignedInfinityRing True
Sage can understand SymPy's complex infinity (:trac:`17493`)::
sage: import sympy sage: SR(sympy.zoo) Infinity
Some equality checks::
sage: infinity == UnsignedInfinityRing.gen() True sage: UnsignedInfinityRing(3) == UnsignedInfinityRing(-19.5) True """ Ring.__init__(self, self, names=('oo',), normalize=False)
def ngens(self): """ The unsigned infinity ring has one "generator."
EXAMPLES::
sage: UnsignedInfinityRing.ngens() 1 sage: len(UnsignedInfinityRing.gens()) 1 """
def fraction_field(self): """ The unsigned infinity ring isn't an integral domain.
EXAMPLES::
sage: UnsignedInfinityRing.fraction_field() Traceback (most recent call last): ... TypeError: infinity 'ring' has no fraction field """
def gen(self, n=0): """ The "generator" of ``self`` is the infinity object.
EXAMPLES::
sage: UnsignedInfinityRing.gen() Infinity sage: UnsignedInfinityRing.gen(1) Traceback (most recent call last): ... IndexError: UnsignedInfinityRing only has one generator """ except AttributeError: self._gen = UnsignedInfinity() return self._gen else:
def gens(self): """ The "generator" of ``self`` is the infinity object.
EXAMPLES::
sage: UnsignedInfinityRing.gens() [Infinity] """
def less_than_infinity(self): """ This is the element that represents a finite value.
EXAMPLES::
sage: UnsignedInfinityRing.less_than_infinity() A number less than infinity sage: UnsignedInfinityRing(5) is UnsignedInfinityRing.less_than_infinity() True """ except AttributeError: self._less_than_infinity = LessThanInfinity(self) return self._less_than_infinity
def _repr_(self): """ Return a string representation of ``self``.
TESTS::
sage: UnsignedInfinityRing._repr_() 'The Unsigned Infinity Ring' """
def _element_constructor_(self, x): """ The element constructor
TESTS::
sage: UnsignedInfinityRing(2) # indirect doctest A number less than infinity sage: UnsignedInfinityRing(I) A number less than infinity sage: UnsignedInfinityRing(unsigned_infinity) Infinity sage: UnsignedInfinityRing(oo) Infinity sage: UnsignedInfinityRing(-oo) Infinity sage: K.<a> = QuadraticField(3) sage: UnsignedInfinityRing(a) A number less than infinity sage: UnsignedInfinityRing(a - 2) A number less than infinity sage: UnsignedInfinityRing(RDF(oo)), UnsignedInfinityRing(RDF(-oo)) (Infinity, Infinity) sage: UnsignedInfinityRing(RR(oo)), UnsignedInfinityRing(RR(-oo)) (Infinity, Infinity) sage: UnsignedInfinityRing(CDF(oo)), UnsignedInfinityRing(CDF(-oo)) (Infinity, Infinity) sage: UnsignedInfinityRing(CC(oo)), UnsignedInfinityRing(CC(-oo)) (Infinity, Infinity) sage: UnsignedInfinityRing(RIF(oo)), UnsignedInfinityRing(RIF(-oo)) (Infinity, Infinity) sage: UnsignedInfinityRing(float('+inf')), UnsignedInfinityRing(float('-inf')) (Infinity, Infinity) sage: UnsignedInfinityRing(SR(oo)), UnsignedInfinityRing(SR(-oo)) (Infinity, Infinity)
The following rings have a ``is_infinity`` method::
sage: RR(oo).is_infinity() True sage: SR(oo).is_infinity() True """ # Lazy elements can wrap infinity or not, unwrap first x = x._value
# Handle all ways to represent infinity first return x else: else: # For example, RealField() implements this
# If we got here then x is not infinite
def _coerce_map_from_(self, R): """ EXAMPLES::
sage: UnsignedInfinityRing.has_coerce_map_from(int) # indirect doctest True sage: UnsignedInfinityRing.has_coerce_map_from(CC) True sage: UnsignedInfinityRing.has_coerce_map_from(QuadraticField(-163, 'a')) True sage: UnsignedInfinityRing.has_coerce_map_from(QQ^3) False sage: UnsignedInfinityRing.has_coerce_map_from(SymmetricGroup(13)) False """
UnsignedInfinityRing = UnsignedInfinityRing_class()
class LessThanInfinity(_uniq, RingElement): def __init__(self, parent=UnsignedInfinityRing): """ Initialize ``self``.
EXAMPLES::
sage: sage.rings.infinity.LessThanInfinity() is UnsignedInfinityRing(5) True """
def _repr_(self): """ Return a string representation of ``self``.
EXAMPLES::
sage: UnsignedInfinityRing(5)._repr_() 'A number less than infinity' """
def _latex_(self): """ Return a latex representation of ``self``.
EXAMPLES::
sage: UnsignedInfinityRing(5)._latex_() '(<\\infty)' """
def _add_(self, other): """ EXAMPLES::
sage: UnsignedInfinityRing(5) + UnsignedInfinityRing(-3) # indirect doctest A number less than infinity sage: UnsignedInfinityRing(5) + unsigned_infinity Infinity """
def _sub_(self, other): """ EXAMPLES::
sage: UnsignedInfinityRing(5) - UnsignedInfinityRing(-3) # indirect doctest A number less than infinity sage: UnsignedInfinityRing(5) - unsigned_infinity Infinity """
def _mul_(self, other): """ EXAMPLES::
sage: UnsignedInfinityRing(4) * UnsignedInfinityRing(-3) # indirect doctest A number less than infinity sage: 5 * unsigned_infinity Traceback (most recent call last): ... ValueError: oo times number < oo not defined sage: unsigned_infinity * unsigned_infinity Infinity """
def _div_(self, other): """ Can't eliminate possibility of zero division....
EXAMPLES::
sage: UnsignedInfinityRing(2) / UnsignedInfinityRing(5) # indirect doctest Traceback (most recent call last): ... ValueError: quotient of number < oo by number < oo not defined sage: 1 / unsigned_infinity 0 """
def _richcmp_(self, other, op): """ Compare ``self`` to ``other``.
EXAMPLES::
sage: 1 == unsigned_infinity False """
class UnsignedInfinity(_uniq, AnInfinity, InfinityElement):
_sign = 0 _sign_char = ''
def __init__(self): """ Initialize ``self``.
TESTS::
sage: sage.rings.infinity.UnsignedInfinity() is sage.rings.infinity.UnsignedInfinity() is unsigned_infinity True """
def __hash__(self): r""" TESTS::
sage: hash(unsigned_infinity) 9223372036854775806 # 64-bit 2147483646 # 32-bit """
def _mul_(self, other): """ Can't rule out an attempt at multiplication by 0.
EXAMPLES::
sage: unsigned_infinity * unsigned_infinity # indirect doctest Infinity sage: unsigned_infinity * 0 Traceback (most recent call last): ... ValueError: unsigned oo times smaller number not defined sage: unsigned_infinity * 3 Traceback (most recent call last): ... ValueError: unsigned oo times smaller number not defined """
def _sympy_(self): """ Converts ``unsigned_infinity`` to sympy ``zoo``.
EXAMPLES::
sage: import sympy sage: SR(unsigned_infinity)._sympy_() zoo sage: gamma(-3)._sympy_() is sympy.factorial(-2) True sage: gamma(-3) is sympy.factorial(-2)._sage_() True """
def _richcmp_(self, other, op): """ Compare ``self`` to ``other``.
EXAMPLES::
sage: 1 == unsigned_infinity False """
unsigned_infinity = UnsignedInfinityRing.gen(0) less_than_infinity = UnsignedInfinityRing.less_than_infinity()
def is_Infinite(x): """ This is a type check for infinity elements.
EXAMPLES::
sage: sage.rings.infinity.is_Infinite(oo) True sage: sage.rings.infinity.is_Infinite(-oo) True sage: sage.rings.infinity.is_Infinite(unsigned_infinity) True sage: sage.rings.infinity.is_Infinite(3) False sage: sage.rings.infinity.is_Infinite(RR(infinity)) False sage: sage.rings.infinity.is_Infinite(ZZ) False """
class SignError(ArithmeticError): """ Sign error exception. """ pass
class InfinityRing_class(Singleton, Ring): def __init__(self): """ Initialize ``self``.
TESTS::
sage: sage.rings.infinity.InfinityRing_class() is sage.rings.infinity.InfinityRing_class() is InfinityRing True
Comparison tests::
sage: InfinityRing == InfinityRing True sage: InfinityRing == UnsignedInfinityRing False """ Ring.__init__(self, self, names=('oo',), normalize=False)
def fraction_field(self): """ This isn't really a ring, let alone an integral domain.
TESTS::
sage: InfinityRing.fraction_field() Traceback (most recent call last): ... TypeError: infinity 'ring' has no fraction field """
def ngens(self): """ The two generators are plus and minus infinity.
EXAMPLES::
sage: InfinityRing.ngens() 2 sage: len(InfinityRing.gens()) 2 """
def gen(self, n=0): """ The two generators are plus and minus infinity.
EXAMPLES::
sage: InfinityRing.gen(0) +Infinity sage: InfinityRing.gen(1) -Infinity sage: InfinityRing.gen(2) Traceback (most recent call last): ... IndexError: n must be 0 or 1 """ else: if n == 0: self._gen0 = PlusInfinity() return self._gen0 elif n == 1: self._gen1 = MinusInfinity() return self._gen1
def gens(self): """ The two generators are plus and minus infinity.
EXAMPLES::
sage: InfinityRing.gens() [+Infinity, -Infinity] """
def is_zero(self): """ The Infinity Ring is not zero
EXAMPLES::
sage: InfinityRing.is_zero() False """
def is_commutative(self): """ The Infinity Ring is commutative
EXAMPLES::
sage: InfinityRing.is_commutative() True """
def _repr_(self): """ Return a string representation of ``self``.
TESTS::
sage: InfinityRing._repr_() 'The Infinity Ring' """
def _element_constructor_(self, x): """ The element constructor
TESTS::
sage: InfinityRing(-oo) # indirect doctest -Infinity sage: InfinityRing(3) A positive finite number sage: InfinityRing(-1.5) A negative finite number sage: [InfinityRing(a) for a in [-2..2]] [A negative finite number, A negative finite number, Zero, A positive finite number, A positive finite number] sage: K.<a> = QuadraticField(3) sage: InfinityRing(a) A positive finite number sage: InfinityRing(a - 2) A negative finite number sage: InfinityRing(RDF(oo)), InfinityRing(RDF(-oo)) (+Infinity, -Infinity) sage: InfinityRing(RR(oo)), InfinityRing(RR(-oo)) (+Infinity, -Infinity) sage: InfinityRing(RIF(oo)), InfinityRing(RIF(-oo)) (+Infinity, -Infinity) sage: InfinityRing(float('+inf')), InfinityRing(float('-inf')) (+Infinity, -Infinity) sage: InfinityRing(SR(oo)), InfinityRing(SR(-oo)) (+Infinity, -Infinity)
The following rings have ``is_positive_infinity`` / ``is_negative_infinity`` methods::
sage: RR(oo).is_positive_infinity(), RR(-oo).is_negative_infinity() (True, True) sage: SR(oo).is_positive_infinity(), SR(-oo).is_negative_infinity() (True, True)
Complex infinity raises an exception. This is fine (there is no coercion, so there is no promise of functoriality)::
sage: i_infinity = CC(0, oo) sage: InfinityRing(CC(oo)), InfinityRing(CC(-oo)) (+Infinity, -Infinity) sage: InfinityRing(i_infinity) Traceback (most recent call last): ... ValueError: infinite but not with +/- phase sage: InfinityRing(CDF(oo)), InfinityRing(CDF(-oo)) (+Infinity, -Infinity) sage: InfinityRing(CDF(i_infinity)) Traceback (most recent call last): ... ValueError: infinite but not with +/- phase """ # Lazy elements can wrap infinity or not, unwrap first
# Handle all ways to represent infinity first else: else: # For example, RealField() implements this
# If we got here then x is not infinite
def _coerce_map_from_(self, R): r""" There is a coercion from anything that has a coercion into the reals.
The way Sage works is that everything that should be comparable with infinity can be coerced into the infinity ring, so if you ever compare with infinity the comparison is done there. If you don't have a coercion then you will get undesirable answers from the fallback comparison (likely memory location).
EXAMPLES::
sage: InfinityRing.has_coerce_map_from(int) # indirect doctest True sage: InfinityRing.has_coerce_map_from(AA) True sage: InfinityRing.has_coerce_map_from(RDF) True sage: InfinityRing.has_coerce_map_from(RIF) True
As explained above, comparison works by coercing to the infinity ring::
sage: cm = get_coercion_model() sage: cm.explain(AA(3), oo, operator.lt) Coercion on left operand via Coercion map: From: Algebraic Real Field To: The Infinity Ring Arithmetic performed after coercions. Result lives in The Infinity Ring The Infinity Ring
The symbolic ring does not coerce to the infinity ring, so symbolic comparisons with infinities all happen in the symbolic ring::
sage: SR.has_coerce_map_from(InfinityRing) True sage: InfinityRing.has_coerce_map_from(SR) False
Complex numbers do not coerce into the infinity ring (what would `i \infty` coerce to?). This is fine since they can not be compared, so we do not have to enforce consistency when comparing with infinity either::
sage: InfinityRing.has_coerce_map_from(CDF) False sage: InfinityRing.has_coerce_map_from(CC) False sage: CC(0, oo) < CC(1) # does not coerce to infinity ring True """ except ImportError: pass
class FiniteNumber(RingElement):
def __init__(self, parent, x): """ Initialize ``self``.
TESTS::
sage: sage.rings.infinity.FiniteNumber(InfinityRing, 1) A positive finite number sage: sage.rings.infinity.FiniteNumber(InfinityRing, -1) A negative finite number sage: sage.rings.infinity.FiniteNumber(InfinityRing, 0) Zero """
def _richcmp_(self, other, op): """ Compare ``self`` and ``other``.
EXAMPLES::
sage: P = InfinityRing sage: -oo < P(-5) < P(0) < P(1.5) < oo True sage: P(1) < P(100) False sage: P(-1) == P(-100) True """
def _add_(self, other): """ EXAMPLES::
sage: P = InfinityRing sage: 4 + oo # indirect doctest +Infinity sage: P(4) + P(2) A positive finite number sage: P(-1) + P(1) Traceback (most recent call last): ... SignError: cannot add positive finite value to negative finite value
Subtraction is implemented by adding the negative::
sage: P = InfinityRing sage: 4 - oo # indirect doctest -Infinity sage: 5 - -oo +Infinity sage: P(44) - P(4) Traceback (most recent call last): ... SignError: cannot add positive finite value to negative finite value sage: P(44) - P(-1) A positive finite number """
def _mul_(self, other): """ EXAMPLES::
sage: P = InfinityRing sage: 0 * oo # indirect doctest Traceback (most recent call last): ... SignError: cannot multiply infinity by zero sage: -1 * oo -Infinity sage: -2 * oo -Infinity sage: 3 * oo +Infinity sage: -oo * oo -Infinity sage: P(0) * 3 0 sage: P(-3) * P(2/3) A negative finite number """ raise SignError("cannot multiply infinity by zero")
def _div_(self, other): """ EXAMPLES::
sage: P = InfinityRing sage: 1 / oo # indirect doctest 0 sage: oo / 4 +Infinity sage: oo / -4 -Infinity sage: P(1) / P(-4) A negative finite number """
def __invert__(self): """ EXAMPLES::
sage: P = InfinityRing sage: ~P(2) A positive finite number sage: ~P(-7) A negative finite number sage: ~P(0) Traceback (most recent call last): ... ZeroDivisionError: Cannot divide by zero """
def _neg_(self): """ EXAMPLES::
sage: a = InfinityRing(5); a A positive finite number sage: -a # indirect doctest A negative finite number sage: -(-a) == a True sage: -InfinityRing(0) Zero """
def _repr_(self): """ Return a string representation of ``self``.
EXAMPLES::
sage: InfinityRing(-2)._repr_() 'A negative finite number' sage: InfinityRing(7)._repr_() 'A positive finite number' sage: InfinityRing(0)._repr_() 'Zero' """
def _latex_(self): """ Return a latex representation of ``self``.
TESTS::
sage: a = InfinityRing(pi); a A positive finite number sage: a._latex_() 'A positive finite number' sage: [latex(InfinityRing(a)) for a in [-2..2]] [A negative finite number, A negative finite number, Zero, A positive finite number, A positive finite number] """
def __abs__(self): """ EXAMPLES::
sage: abs(InfinityRing(-3)) A positive finite number sage: abs(InfinityRing(3)) A positive finite number sage: abs(InfinityRing(0)) Zero """
def sqrt(self): """ EXAMPLES::
sage: InfinityRing(7).sqrt() A positive finite number sage: InfinityRing(0).sqrt() Zero sage: InfinityRing(-.001).sqrt() Traceback (most recent call last): ... SignError: cannot take square root of a negative number """
class MinusInfinity(_uniq, AnInfinity, InfinityElement):
_sign = -1 _sign_char = '-'
def __init__(self): """ Initialize ``self``.
TESTS::
sage: sage.rings.infinity.MinusInfinity() is sage.rings.infinity.MinusInfinity() is -oo True """
def __hash__(self): r""" TESTS::
sage: hash(-infinity) -9223372036854775808 # 64-bit -2147483648 # 32-bit """
def _richcmp_(self, other, op): """ Compare ``self`` and ``other``.
EXAMPLES::
sage: P = InfinityRing sage: -oo < P(-5) < P(0) < P(1.5) < oo True sage: P(1) < P(100) False sage: P(-1) == P(-100) True """
def _neg_(self): """ EXAMPLES::
sage: -(-oo) # indirect doctest +Infinity """
def sqrt(self): """ EXAMPLES::
sage: (-oo).sqrt() Traceback (most recent call last): ... SignError: cannot take square root of negative infinity """
def _sympy_(self): """ Converts ``-oo`` to sympy ``-oo``.
Then you don't have to worry which ``oo`` you use, like in these examples:
EXAMPLES::
sage: import sympy sage: bool(-oo == -sympy.oo) True sage: bool(SR(-oo) == -sympy.oo) True sage: bool((-oo)._sympy_() == -sympy.oo) True
"""
def _gap_init_(self): r""" Conversion to gap and libgap.
EXAMPLES::
sage: gap(-Infinity) -infinity sage: libgap(-Infinity) -infinity """
class PlusInfinity(_uniq, AnInfinity, InfinityElement):
_sign = 1 _sign_char = '+'
def __init__(self): """ Initialize ``self``.
TESTS::
sage: sage.rings.infinity.PlusInfinity() is sage.rings.infinity.PlusInfinity() is oo True """
def __hash__(self): r""" TESTS::
sage: hash(+infinity) 9223372036854775807 # 64-bit 2147483647 # 32-bit """
def _richcmp_(self, other, op): """ Compare ``self`` and ``other``.
EXAMPLES::
sage: P = InfinityRing sage: -oo < P(-5) < P(0) < P(1.5) < oo True sage: P(1) < P(100) False sage: P(-1) == P(-100) True """
def _neg_(self): """ TESTS::
sage: -oo # indirect doctest -Infinity """
def sqrt(self): """ The square root of ``self``.
The square root of infinity is infinity.
EXAMPLES::
sage: oo.sqrt() +Infinity """
def _sympy_(self): """ Converts ``oo`` to sympy ``oo``.
Then you don't have to worry which ``oo`` you use, like in these examples:
EXAMPLES::
sage: import sympy sage: bool(oo == sympy.oo) # indirect doctest True sage: bool(SR(oo) == sympy.oo) True """
def _gap_init_(self): r""" Conversion to gap and libgap.
EXAMPLES::
sage: gap(+Infinity) infinity sage: libgap(+Infinity) infinity """
InfinityRing = InfinityRing_class() infinity = InfinityRing.gen(0) Infinity = infinity minus_infinity = InfinityRing.gen(1)
def test_comparison(ring): """ Check comparison with infinity
INPUT:
- ``ring`` -- a sub-ring of the real numbers
OUTPUT:
Various attempts are made to generate elements of ``ring``. An assertion is triggered if one of these elements does not compare correctly with plus/minus infinity.
EXAMPLES::
sage: from sage.rings.infinity import test_comparison sage: rings = [ZZ, QQ, RR, RealField(200), RDF, RLF, AA, RIF] sage: for R in rings: ....: print('testing {}'.format(R)) ....: test_comparison(R) testing Integer Ring testing Rational Field testing Real Field with 53 bits of precision testing Real Field with 200 bits of precision testing Real Double Field testing Real Lazy Field testing Algebraic Real Field testing Real Interval Field with 53 bits of precision
Comparison with number fields does not work::
sage: K.<sqrt3> = NumberField(x^2-3) sage: (-oo < 1+sqrt3) and (1+sqrt3 < oo) # known bug False
The symbolic ring handles its own infinities, but answers ``False`` (meaning: cannot decide) already for some very elementary comparisons::
sage: test_comparison(SR) # known bug Traceback (most recent call last): ... AssertionError: testing -1000.0 in Symbolic Ring: id = ... """ 3 ** (-QQ.one()/3), SR.pi(), 100000]
def test_signed_infinity(pos_inf): """ Test consistency of infinity representations.
There are different possible representations of infinity in Sage. These are all consistent with the infinity ring, that is, compare with infinity in the expected way. See also :trac:`14045`
INPUT:
- ``pos_inf`` -- a representation of positive infinity.
OUTPUT:
An assertion error is raised if the representation is not consistent with the infinity ring.
Check that :trac:`14045` is fixed::
sage: InfinityRing(float('+inf')) +Infinity sage: InfinityRing(float('-inf')) -Infinity sage: oo > float('+inf') False sage: oo == float('+inf') True
EXAMPLES::
sage: from sage.rings.infinity import test_signed_infinity sage: for pos_inf in [oo, float('+inf'), RLF(oo), RIF(oo), SR(oo)]: ....: test_signed_infinity(pos_inf) """ |