>>> class _infinity:
... def __lt__(self, n): return 0
... def __gt__(self, n): return 1
...
>>> infinity = _infinity()
>>> infinity < 9
0
>>> infinity > 99999
1
>>> 99999 < infinity
1
So far so good. But here comes the surprise:
>>> infinity >= 3
0
I wouldn't have predicted this from the description in the docs. It
turns out that since there's no __ge__ method and no __cmp__ method,
the interpreter compared the machine addresses of the infinity object
and the "3" object. The comparison came out one way but could have
come out the other way (or maybe I might have defined "minus infinity"
instead of infinity). It could have been hard to discover this bug by
testing.
Anyway, the right way to implement infinity is with
def __cmp__(self, n): return 1
I only figured all this out after starting to write this post to ask
what was causing the >= anomaly. I decided to post anyway, as a
cautionary tale.
> I want to define an "infinite" numeric object, that's greater than
> any regular number. I do the obvious (Python 2.2):
>
> >>> class _infinity:
> ... def __lt__(self, n): return 0
> ... def __gt__(self, n): return 1
> ...
> >>> infinity = _infinity()
> >>> infinity < 9
> 0
> >>> infinity > 99999
> 1
> >>> 99999 < infinity
> 1
>
> So far so good. But here comes the surprise:
>
> >>> infinity >= 3
> 0
Python has builtin infinity:
#v+
$ python
Python 2.2.2 (#1, Jan 18 2003, 10:18:59)
[GCC 3.2.2 20030109 (Debian prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Welcome to rlcompleter2 0.95
for nice experiences hit <tab> multiple times
>>> infinity = float('Inf')
>>> infinity < 9
0
>>> infinity > 99999
1
>>> 99999 < infinity
1
>>> infinity >= 3
1
>>> ^D
$
#v-
You can use "float('-Inf')" and "float('NaN')", too.
// Klaus
--
><> vandag, môre, altyd saam
>
> Python has builtin infinity:
>
> #v+
>
> $ python
> Python 2.2.2 (#1, Jan 18 2003, 10:18:59)
> [GCC 3.2.2 20030109 (Debian prerelease)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> Welcome to rlcompleter2 0.95
> for nice experiences hit <tab> multiple times
> >>> infinity = float('Inf')
> >>> infinity < 9
> 0
> >>> infinity > 99999
> 1
> >>> 99999 < infinity
> 1
> >>> infinity >= 3
> 1
> >>> ^D
> $
>
> #v-
>
> You can use "float('-Inf')" and "float('NaN')", too.
>
Unfortunately, that's entirely platform specific. Neither of the two
platforms I have here at home support float('Inf'), as shown below...
On Win2k:
Python 2.2.1 (#34, Apr 9 2002, 19:34:33) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
IDLE 0.8 -- press F1 for help
>>> infinity = float('Inf')
Traceback (most recent call last):
File "<pyshell#0>", line 1, in ?
infinity = float('Inf')
ValueError: invalid literal for float(): Inf
>>>
On FreeBSD:
[GCC 2.95.3 20010315 (release) [FreeBSD]] on freebsd4
Type "help", "copyright", "credits" or "license" for more information.
>>> infinity = float('Inf')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: invalid literal for float(): Inf
>>>
--Paul
You can use the __cmp__ overloader:
21 >>> class A:
21 ... def __cmp__(self, other):
21 ... return 1
21 ...
22 >>> A() > 5
True
23 >>> A() < 9
False
24 >>> A() >= 3
True
See also:
http://www.python.org/dev/doc/devel/ref/customization.html#l2h-97
yours,
Gerrit.
--
Asperger Syndroom - een persoonlijke benadering:
http://people.nl.linux.org/~gerrit/
Het zijn tijden om je zelf met politiek te bemoeien:
http://www.sp.nl/
> Python 2.2.1 (#34, Apr 9 2002, 19:34:33) [MSC 32 bit (Intel)] on win32
> Type "copyright", "credits" or "license" for more information.
> IDLE 0.8 -- press F1 for help
>>>> infinity = float('Inf')
> Traceback (most recent call last):
> File "<pyshell#0>", line 1, in ?
> infinity = float('Inf')
> ValueError: invalid literal for float(): Inf
Hm, too bad.
GH> You can use the __cmp__ overloader:
GH> 21 >>> class A:
GH> 21 ... def __cmp__(self, other):
GH> 21 ... return 1
GH> 21 ...
GH> 22 >>> A() > 5
GH> True
GH> 23 >>> A() < 9
GH> False
GH> 24 >>> A() >= 3
GH> True
>>> inf = A()
>>> inf > inf
True
>>> inf == inf
False
>>>
--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.van....@hccnet.nl
This is correct, or wrong?
-gustavo
S> This is correct, or wrong?
I would consider that incorrect. But others may differ. But if it is
considered correct, then > is not an ordering for sets that include inf.
On the other hand, in Python > isn't an ordering in general.
> > >>> inf = A()
> > >>> inf > inf
> > True
> > >>> inf == inf
> > False
> > >>>
> >
>
> This is correct, or wrong?
Depends on your background and motivation for providing an "infinity"
that compares greater than all numbers. It's easy enought to fix by
doing an isinstance test against the infinity class, and then changing
the behavior however you'd like.
Infinity is not really a number, it's a concept of something greater
than all numbers. Among transfinite cardinals, there are numbers which
represent "infinity" that are greater or less than other "infinities."
Really asking whether infinity equals itself should be indeterminate,
rather than false. Whether that should raise an exception or just
return false values depends on the precise motivation for including
infinities in the first place.
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ I am a gentlemen: I live by robbing the poor.
\__/ George Bernard Shaw
Blackgirl International / http://www.blackgirl.org/
The Internet resource for black women.
If __cmp__() returns 1, then "inf == inf" can't ever be true,
because __cmp__() is actually saying that it's larger.
-gustavo
This is correct of course. By having __cmp__ return 1 *always*, you
are saying inf is greater than *anything* else without regard to what
the other thing is. (Note that your __cmp__ does not even look at the
second argument.) It will never compare equal to anything (__cmp__
would need to return a zero for that).
Thus
inf > ...any python object...
returns True because __cmp__ returns 1 (meaning "is greater than") and
inf == ...any python object...
returns False because __cmp__ returns 1 (meaning "is greater than" --
not "equal to").
Did you perhaps miss that __cmp__ must return one of three casses:
negative integer: meaning "self is less than other"
0: meaning "self is equal to other"
positive integer: meaning "self is greater than other"
Gary Herron
S> If __cmp__() returns 1, then "inf == inf" can't ever be true,
S> because __cmp__() is actually saying that it's larger.
Yes, of course, but I mean that I consider this an incorrect
definition of __cmp__.
class A:
def __cmp__(self, other):
return self is not other
would be better.
Actually, Python's > *is* an ordering, but he is *not* using
python's > operator. He has redefined it (in a silly fashion)
with the __cmp__ method.
Gary Herron
> Yes, of course, but I mean that I consider this an incorrect
> definition of __cmp__.
>
> class A:
> def __cmp__(self, other):
> return self is not other
> would be better.
Hmm, I guess that's an improvement but still leaves an anomaly:
inf1 = A()
inf2 = A()
print (inf1 == inf2)
would then print 0.
Anyway I didn't really need a general infinity. I just wanted a simple
way to write a loop with an optional maximum count:
n = 0
while n <= limit:
if some_test(sequence[n]):
break
Letting limit be infinite was the simplest way of expressing that I
sometimes didn't want to have a limit.
"Neutral infinity"?
It's more "neutral" than anything else.
...must be Swiss.
-gus
On Thu, 2003-02-20 at 13:30, Gary Herron wrote:
> > > From: Piet van Oostrum [mailto:pi...@cs.uu.nl]
> > > Sent: Thursday, February 20, 2003 4:56 AM
> > >
> > > >>>>> Gerrit Holl <ger...@nl.linux.org> (GH) schreef:
> > >
> > > GH> You can use the __cmp__ overloader:
> > >
> > > GH> 21 >>> class A:
> > > GH> 21 ... def __cmp__(self, other):
> > > GH> 21 ... return 1
> > > GH> 21 ...
> > > GH> 22 >>> A() > 5
> > > GH> True
> > > GH> 23 >>> A() < 9
> > > GH> False
> > > GH> 24 >>> A() >= 3
> > > GH> True
> > >
> > > >>> inf = A()
> > > >>> inf > inf
> > >
> > > True
> > >
> > > >>> inf == inf
> > >
> > > False
> This is correct of course. By having __cmp__ return 1 *always*, you
> are saying inf is greater than *anything* else without regard to what
> the other thing is. (Note that your __cmp__ does not even look at the
> second argument.) It will never compare equal to anything (__cmp__
> would need to return a zero for that).
While I understand that this is the correct behavior for the above
implementation, I wonder if the implicit question wasn't "Shouldn't
infinity evaluate to be equal to infinity?"
Interestingly, Java considers the cases of both positive and negative
infinity. They are respectively greater than and less than everything
(except themselves); they are equal to themselves only.
Here's a slightly different snippet to break:
class INFINITY:
def __init__(self, type = 1) :
self.sign = cmp(type, 0)
if not self.sign: self.sign = 1
def __cmp__(self, other) :
if isinstance(other, INFINITY) :
return cmp(self.sign, other.sign)
else :
return self.sign
>>> posinf = INFINITY()
>>> neginf = INFINITY(-1)
>>> 1 > neginf
1
>>> 1 < posinf
1
>>> neginf > posinf
0
>>> posinf > neginf
1
>>> posinf > posinf
0
>>> posinf < posinf
0
>>> posinf == posinf
1
You get the idea.
--j, who wonders if 'self.sign = 0' might ever be interesting ...
--
Jim Meyer, Geek at Large jme...@pdi.com
Yeah, my original implementation had signed infinity, but then I
realized I only needed positive infinity, so I took out the sign.
Actually, my *original* original implementation had infinity compare
both larger than everything and smaller than everything. The
application is something like regexps: pat{m,n} means k occurences
of pat, for some m <= k <= n, but both values default to "no limit".
So I wanted to have a single object that I could use as the default
for either m or n. But it turned out to be simpler to just
default m to 0 (I don't have to worry about negative values).
No his question was not about what properties a representation of
infinity *should* have, but rather why his particular object was
exhibiting the behavior he was seeing. Once one understands the
behavior of his "inf", one can attempt to produce a less naive and
more useful representation of infinity which exhibits the desired
behavior.
Gary Herron
Infinity as a limit needs either to be positive infinity or negative
infinity; if unstated, it's positive infinity. There's no "unsigned
infinity."
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ Success and failure are equally disastrous.
\__/ Tennessee Williams
Polly Wanna Cracka? / http://www.pollywannacracka.com/
The Internet resource for interracial relationships.
> While I understand that this is the correct behavior for the above
> implementation, I wonder if the implicit question wasn't "Shouldn't
> infinity evaluate to be equal to infinity?"
The answer really depends on what you're using the infinities for. In
transfinite cardinals, you can easily talk about "an infinity" that is
larger than "another infinity."
In limit theory, "infinity" just means "the limit does not exist in that
the value increases (or decreases) without bound." Infinity isn't a
number, so talking about it equally another infinity is getting into a
problem zone.
IEEE 754 supports unsigned (projective) infinity. This is useful for
complex arithmetic, among other things. The extended complex numbers
include projective infinity. There's no positive or negative
infinity.
There can be. google on
infinity affine projective 754
for recent history about this choice in relation to computer arithmetic.
The Intel 8087 floating-point coprocessor actually had a hardware flag to
choose between affine (two signed infinities) and projective (one signless
infinity) modes of operation. Before its final draft, 754 switched from
specifying that projective mode was the default to dropping projective mode
altogether. This was a contentious decision at the time. Python still
ignores the issue entirely <wink>.
If I've understood your code correctly, with self.sign == 0 we'd
have
-inf < 0inf < +inf
and 0inf would compare as equal to all other objects (at least
when it was on the left-hand side of the comparison).
In a sense, then, 0inf means "an arbitrary finite number". Using
"INFINITY(0) == x" to test "x is finite" is a little odd, but the
test itself is useful. (It looks (very slightly) more sensible as
"INFINITY(False) == x".)
--
Steven Taschuk stas...@telusplanet.net
"What I find most baffling about that song is that it was not a hit."
-- Tony Dylan Davis (CKUA)
There are uses for algebras on R U {oo}, that is, the real numbers
augmented with a single unsigned infinity. Gosper refers to such
an algebra in his algorithms for continued fraction arithmetic,
for example.
If memory serves, the similar C U {oo}, i.e., the complex plane
augmented with a single "point at infinity", finds use in complex
analysis. I think that set even has a name, but I'm damned if I
can remember it.
However, I don't know of a case in which having separate -oo, +oo
and oo all at once is useful. The closest thing I can think of is
allowing the value 0/0 in rational arithmetic, but that's better
conceived of as a NaN than as an infinity.
--
Steven Taschuk stas...@telusplanet.net
Every public frenzy produces legislation purporting to address it.
(Kinsley's Law)
>Quoth Erik Max Francis:
> [...]
>> Infinity as a limit needs either to be positive infinity or negative
>> infinity; if unstated, it's positive infinity. There's no "unsigned
>> infinity."
>
>There are uses for algebras on R U {oo}, that is, the real numbers
>augmented with a single unsigned infinity. Gosper refers to such
>an algebra in his algorithms for continued fraction arithmetic,
>for example.
>
You can viw this as the circle S^1.
>If memory serves, the similar C U {oo}, i.e., the complex plane
>augmented with a single "point at infinity", finds use in complex
>analysis. I think that set even has a name, but I'm damned if I
>can remember it.
>
It's the Riemman Sphere by golly. The infinity is the north pole. You
can also view it as the projective space of lines in R^2. Or...
>However, I don't know of a case in which having separate -oo, +oo
>and oo all at once is useful. The closest thing I can think of is
>allowing the value 0/0 in rational arithmetic, but that's better
>conceived of as a NaN than as an infinity.
There are inumerous cases where adding a point of infinity is essential.
It is the simplest method of compactifying a space. And now that I am
studying Thom Spectra, it is also one of the essential tricks in the
Thom construction. The list goes on.
Uh..., wait... this is a Python newsgroup right? *crawls away*
With my best regards,
G. Rodrigues
GH> Actually, Python's > *is* an ordering, but he is *not* using
GH> python's > operator. He has redefined it (in a silly fashion)
GH> with the __cmp__ method.
What I meant is that, if you use '>', you usually expect it to have the
properties of an ordering. That implementation did not have that property.
Most people probably even expect it to be a total ordering.
And nom Python's > is *not* an ordering, at least not for general objects.
It is possible to have a > b > a for certain objects a and b.