[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