On Sun, Jul 18, 2010 at 3:36 PM, Pauli Virtanen <pav@iki.fi> wrote:
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.
The sort and cmp order was defined in 1.4.0, see the release notes. (z,z), (z, nan), (nan, z), (nan, nan) are in correct order and there are tests to enforce this. Sort and searchsorted need to work together. - Moreover, all comparisons <, >, ==, <=, >= where one or more operands
is a cnan are false.
- Except that when sorting, cnans are to be placed last.
And in sort order.
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).
Chuck