[Numpy-discussion] Complex nan ordering

Pauli Virtanen pav@iki...
Sun Jul 18 16:36:14 CDT 2010


Hi,

The current way of Numpy handles ordering of complex nan is not very well 
defined. We should attempt to clarify this for 1.5.0.

For example, what should these return:

    r1 = np.maximum(complex(1, nan), complex(2, 0))

    r2 = np.complex64(complex(1, nan)) < np.complex64(complex(2, 0))

or, what should `r3` be after this:

    r3 = np.array([complex(3, nan), complex(1, 0), complex(nan, 2)])
    r3.sort()

Previously, we have defined a lexical ordering relation for complex 
numbers,

    x < y  iff  x.real < y.real or (x.real == y.real and x.imag < y.imag)

but applying this to the above can cause some surprises:

    amax([1, 2, 4, complex(3, nan)]) == 4

which breaks nan propagation, and moreover the result depends on the 
order of the items, and the precise way the algorithm is written.

    ***

Numpy IIRC has specified a lexical order between complex numbers for some 
time now, unlike Python in which complex numbers are unordered.

So we won't change how finite numbers are handled, only the nan handling 
needs to be specified.

    ***

I suggest the following, aping the way the real nan works:

- (z, nan), (nan, z), (nan, nan), where z is any fp value, are all
  equivalent representations of "cnan", as far as comparisons, sort
  order, etc are concerned. 

- The ordering between (z, nan), (nan, z), (nan, nan) is undefined. This
  means e.g. that maximum([cnan_1, cnan_2]) can return either cnan_1 or
  cnan_2 if both are some cnans.

- Moreover, all comparisons <, >, ==, <=, >= where one or more operands
  is a cnan are false.

- Except that when sorting, cnans are to be placed last.

The advantages are now that nan propagation is now easier to implement, 
and we get faster code. Moreover, complex nans start to behave more 
similarly as their real counterparts in comparisons etc.; for instance in 
the above cases

    r1 = (1, nan)
    r2 = False
    r3 = [complex(1, 0), complex(3, nan), complex(nan, 2)]

where in `r3` the order of the last two elements is unspecified.

This is in fact the SVN trunk now works (final tweaks in r8508, 8509). 

Comments are welcome.

-- 
Pauli Virtanen



More information about the NumPy-Discussion mailing list