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.
$ 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
> $ 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 M wrote: > 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
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. -- Piet van Oostrum <p...@cs.uu.nl> URL: http://www.cs.uu.nl/~piet [PGP] Private email: P.van.Oost...@hccnet.nl
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.
> 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. > --
If __cmp__() returns 1, then "inf == inf" can't ever be true, because __cmp__() is actually saying that it's larger.
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"
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. -- Piet van Oostrum <p...@cs.uu.nl> URL: http://www.cs.uu.nl/~piet [PGP] Private email: P.van.Oost...@hccnet.nl
> 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.
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.
> > > 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
Jim Meyer <jme...@pdi.com> writes: > 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.
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).
> On Thu, 2003-02-20 at 13:30, Gary Herron wrote: > > > > From: Piet van Oostrum [mailto:p...@cs.uu.nl] > > > > Sent: Thursday, February 20, 2003 4:56 AM
> > > > >>>>> Gerrit Holl <ger...@nl.linux.org> (GH) schreef:
> > 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?"
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.
sisme...@hebmex.com wrote: > > From: Jim Meyer [mailto:jme...@pdi.com] > > Sent: Thursday, February 20, 2003 4:28 PM
> > --j, who wonders if 'self.sign = 0' might ever be interesting ...
> "Neutral infinity"? > It's more "neutral" than anything else.
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.
Jim Meyer wrote: > 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.
-- 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.
> Infinity as a limit needs either to be positive infinity or negative > infinity; if unstated, it's positive infinity. There's no "unsigned > infinity."
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.
> 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 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>.
> 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 [...] > --j, who wonders if 'self.sign = 0' might ever be interesting ...
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 stasc...@telusplanet.net "What I find most baffling about that song is that it was not a hit." -- Tony Dylan Davis (CKUA)
> 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.
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 stasc...@telusplanet.net Every public frenzy produces legislation purporting to address it. (Kinsley's Law)
On Thu, 20 Feb 2003 22:58:15 -0700, Steven Taschuk
<stasc...@telusplanet.net> wrote: >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*