Re: Rich Comparisons Gotcha



Rasmus Fogh wrote:
Current behaviour is both inconsistent and counterintuitive, as these
examples show.

x = float('NaN')
x == x
False

Perhaps this should raise an exception? I think the problem is not with comparisons in general but with the fact that nan is type float:

py> type(float('NaN'))
<type 'float'>

No float can be equal to nan, but nan is a float. How can something be not a number and a float at the same time? The illogicality of nan's type creates the possibility for the illogical results of comparisons to nan including comparing nan to itself.

ll = [x]
x in ll
True
x == ll[0]
False

But there is consistency on the basis of identity which is the test for containment (in):

py> x is x
True
py> x in [x]
True

Identity and equality are two different concepts. Comparing identity to equality is like comparing apples to oranges ;o)


import numpy
y = numpy.zeros((3,))
y
array([ 0., 0., 0.])
bool(y==y)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is
ambiguous. Use a.any() or a.all()

But the equality test is not what fails here. It's the cast to bool that fails, which for numpy works like a unary ufunc. The designers of numpy thought that this would be a more desirable behavior. The test for equality likewise is a binary ufunc and the behavior was chosen in numpy for practical reasons. I don't know if you can overload the == operator in C, but if you can, you would be able to achieve the same behavior.

ll1 = [y,1]
y in ll1
True
ll2 = [1,y]
y in ll2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is
ambiguous. Use a.any() or a.all()

I think you could be safe calling this a bug with numpy. But the fact that someone can create a bug with a language is not a condemnation of the language. For example, C makes it real easy to crash a program by overrunning the limits of an array, but no one would suggest to remove arrays from C.

Can anybody see a way this could be fixed (please)? I may well have to
live with it, but I would really prefer not to.

Your only hope is to somehow convince the language designers to remove the ability to overload == then get them to agree on what you think the proper behavior should be for comparisons. I think the probability of that happening is about zero, though, because such a change would run counter to the dynamic nature of the language.

James


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com
.



Relevant Pages

  • numpy NaN, not surviving pickle/unpickle?
    ... I am aware that numpy has its own discussion group, ... I am pickling numpy.ndarray objects to disk which are of type "float", ... objects and then test for the presence of NaN, ...
    (comp.lang.python)
  • [ANN] Numpy 1.3.0 released
    ... I am pleased to announce the release of numpy 1.3.0. ... Each generalized ufunc has information associated with it that states what the ... The list of the core dimensions for all arguments is called the ... Special values (inf and nan) are also more consistent across platforms (nan vs ...
    (comp.lang.python.announce)
  • Re: RfD: IEEE-FP
    ... > We really don't need to be breaking double-numbers in the language! ... >> constant for NaN, and I'll add myself to the list. ... The second leaves the load as |d| and sign ... completely little endian for higher precision fp. ...
    (comp.lang.forth)
  • Re: Problem with log function - Intel fortran compiler under Linux
    ... compiler under Linux ... an NaN (while the argument is a perfectly acceptable value of about ... Linux: Red Hat Enterprise Linux, ... I then tried with debugging on and array bound checking ...
    (comp.lang.fortran)
  • Re: Comparing floating point values in Java
    ... I was calculating an array of float values from some user input. ... Having a magic value isn't generally a good idea, although NaN would be ... Using any magic value, including NaN, has the risk that a bug elsewhere ...
    (comp.lang.java.programmer)