sign(z) = z/|z| is a fairly standard definition. See https://oeis.org/wiki/Sign_function and https://en.wikipedia.org/wiki/Sign_function. It's also implemented this way in MATLAB and Mathematica (see https://www.mathworks.com/help/symbolic/sign.html and https://reference.wolfram.com/language/ref/Sign.html). The function z/|z| is useful because it represents a normalization of z as a vector in the complex plane onto the unit circle. With that being said, I'm not so sure about the suggestion about extending copysign(x1, x2) as |x1|*sign(x2). I generally think of copysign as a function to manipulate the floating-point representation of a number. It literally copies the sign *bit* from x2 into x1. It's useful because of things like -0.0, which is otherwise difficult to work with since it compares equal to 0.0. I would find it surprising for copysign to do a numeric calculation on complex numbers. Also, your suggested definition would be wrong for 0.0 and -0.0, since sign(0) is 0, and this is precisely where copysign matters. I suppose one could make sense of copysign(x1, x2) where x1 is complex and x2 is float, by copying the sign of x2 into both components of x1. Although I would suggest only adding such a thing if there's an actual need for it. I imagine presently if anyone does need this they just use copysign(x1.view(float64), x2).view(complex128). Aaron Meurer On Sat, Dec 23, 2023 at 8:36 AM Dom Grigonis <dom.grigonis@gmail.com> wrote:

To me this sounds like a reasonable change.

It does seem like there is a return value which is more sensible than alternatives.

And the fact that sympy is already doing that indicates that same conclusion was reached more than once.

I am not dealing much with complex numbers at the moment, but I see this being of non-trivial convenience when I need to.

Regards, DG

On 22 Dec 2023, at 15:48, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:

On Fri, 22 Dec 2023 at 13:25, <mhvk@astro.utoronto.ca> wrote:

Anyway, to me the main question would be whether this would break any workflows (though it is hard to see how it could, given that the previous definition was really rather useless...).

SymPy already defines sign(z) as z/abs(z) (with sign(0) = 0) as proposed here.

Checking this I see that the current mismatch causes a bug when SymPy's lambdify function is used to evaluate the sign function with NumPy:

In [12]: sign(z).subs(z, 1+1j) Out[12]: 0.707106781186548 + 0.707106781186548⋅ⅈ

In [13]: lambdify(z, sign(z))(1+1j) # uses numpy Out[13]: (1+0j)

The proposed change to NumPy's sign function would fix this bug.

-- Oscar _______________________________________________ NumPy-Discussion mailing list -- numpy-discussion@python.org To unsubscribe send an email to numpy-discussion-leave@python.org https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ Member address: dom.grigonis@gmail.com

_______________________________________________ NumPy-Discussion mailing list -- numpy-discussion@python.org To unsubscribe send an email to numpy-discussion-leave@python.org https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ Member address: asmeurer@gmail.com