Tim,

Does 754 say anything about complex numbers?

It strikes me that what is needed is a defined behavior for
complex numbers, rather than expecting them to magically work for all the
edge cases simply by applying the algebraic rules with two floats.

Your example of a complex infinity that should be one thing is a good one.
Maybe the same for complex zero :-)

Anyway, Python is probably not the place to define a standard like this,
but if there's a good one out there, then using it in Python could be nice.

-CHB





On Tue, Feb 22, 2022 at 6:41 PM Tim Peters <tim.pet...@gmail.com> wrote:

> I have to say that signed zeroes and signed infinities don't work well
> in 754 for complex numbers. I know Kahan _wanted_ signed zeroes to
> help sort out branch cuts for complex functions, but he appears to be
> alone in the world in finding them useful for that ;-)
>
> Complex multiplication for values with signed zero components isn't
> even associative. At least not under any implementation I've tried. I
> pointed that out on David Hough's "numeric-interest" mailing list
> while 754 was still being hammered out, but it was "already too late"
> to do anything about it.
>
> Here's a short driver:
>
>     from itertools import product
>     pz = 0.0
>     cs = [complex(*t) for t in product((pz, -pz), repeat=2)]
>     for x, y, z in product(cs, repeat=3):
>         t1 = (x*y)*z
>         t2 = x*(y*z)
>         if repr(t1) != repr(t2):
>             print(x, y, z, t1, t2)
>
> On my Windows 3.10.1, associativity fails in 24 (of the 64) cases:
>
> 0j 0j (-0-0j) -0j 0j
> 0j -0j (-0+0j) (-0+0j) 0j
> 0j -0j (-0-0j) -0j (-0+0j)
> 0j (-0+0j) (-0+0j) -0j 0j
> 0j (-0-0j) -0j -0j (-0+0j)
> 0j (-0-0j) (-0-0j) (-0+0j) 0j
> -0j 0j (-0+0j) (-0+0j) 0j
> -0j -0j (-0-0j) (-0+0j) 0j
> -0j (-0+0j) (-0+0j) (-0+0j) -0j
> -0j (-0+0j) (-0-0j) -0j 0j
> -0j (-0-0j) 0j (-0+0j) -0j
> -0j (-0-0j) (-0+0j) -0j 0j
> (-0+0j) 0j -0j 0j (-0+0j)
> (-0+0j) -0j 0j 0j (-0+0j)
> (-0+0j) (-0+0j) 0j 0j -0j
> (-0+0j) (-0+0j) -0j -0j (-0+0j)
> (-0+0j) (-0-0j) -0j 0j -0j
> (-0+0j) (-0-0j) (-0-0j) -0j (-0+0j)
> (-0-0j) 0j 0j 0j -0j
> (-0-0j) -0j 0j (-0+0j) -0j
> (-0-0j) -0j -0j 0j (-0+0j)
> (-0-0j) (-0+0j) -0j 0j -0j
> (-0-0j) (-0-0j) 0j 0j (-0+0j)
> (-0-0j) (-0-0j) (-0+0j) (-0+0j) -0j
>
> That isn't just academic. My employer's FORTRAN compiler failed to
> pass the US govt's validation suite at the time, because of a bizarre
> test failure: the accidental signs of these zeroes can have very
> visible consequences (e.g., as arguments to atan2(), which the
> validation suite called on the real and imag components after raising
> a complex zero to an integer power - and _which_ of the four complex
> zeroes you got depended on the grouping of the multiplies).
>
> Don't try to sell me the idea that any of that is logical ;-) BTW,
> exactly which cases in the above fail can also depend on the rounding
> mode (because x + -x is +0 for any finite x, _except_ under
> to-minus-infinity rounding, where the result changes to -0).
>
> Signed infinities are even sillier here. You want a single projective
> infinity in the complex plane, not a pair of signed infinities on each
> axis. And early drafts of 754 had a control bit to determine which
> flavor of infinity you got. But it's one of the few bits of esoterica
> that got dropped near the end. Partly because signed zeroes seemingly
> demand signed infinities too, like lutefisk demands haggis ;-)
>
> There was much to applaud in 754, but to my eyes signed zeroes, and
> NaN != NaN, caused far more trouble than they helped - and the
> exception model is such a pain it's almost never been implemented as
> intended (Python's `decimal` module being an exception, and Apple's
> long-dead SANE environment).
>
> BTW, complex was added as a full-blown built-in type in 1.4b1, long
> before Python had a major user base (mid-1990s). I think Guido added
> it because he was trained as a mathematician, so felt obligated ;-)
> Seriously, various Python versions of it (and rationals) were long in
> use as test cases for hammering out rules and APIs for coercion (and
> other native language features).
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/3IY3NTJRAMSQZYTCVQABTYPM2TGS3UVN/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ZXPQ5CUCMKLXBGRM352BHW72QLPIL2DP/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to