Numpy: np.floor_divide drops imaginary part silently

Created on 1 Apr 2019  ·  13Comments  ·  Source: numpy/numpy

Reproducing code example:

import numpy as np
a = np.arange(10) + 1j* np.arange(10)
a
# array([0.+0.j, 1.+1.j, 2.+2.j, 3.+3.j, 4.+4.j, 5.+5.j, 6.+6.j, 7.+7.j,
#           8.+8.j, 9.+9.j])
a / 2
# array([0. +0.j , 0.5+0.5j, 1. +1.j , 1.5+1.5j, 2. +2.j , 2.5+2.5j,
#          3. +3.j , 3.5+3.5j, 4. +4.j , 4.5+4.5j])
a // 2
# array([0.+0.j, 0.+0.j, 1.+0.j, 1.+0.j, 2.+0.j, 2.+0.j, 3.+0.j, 3.+0.j,
#          4.+0.j, 4.+0.j])

Is there a special reason for this behavior? I would expect to floor_divide the imaginary and complex part.

Error message:

No error or warning is thrown, not even that imaginary part is getting lost.

Numpy/Python version information:

1.16.1
3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0]

00 - Bug 15 - Discussion numpy.ufunc

All 13 comments

You can't have a floor function for complex numbers.
Floor of Complex Numbers
Also, we don't divide the imaginary part and complex part separately. We get one complex number on dividing 2 complex numbers. (Dividing complex numbers)

Also ,
`>>> (1. + 1.j) // 2

Traceback (most recent call last):
File "", line 1, in
TypeError: can't take floor of complex number.`

Similary it should show TypeError.
I am new to open Source. I would like to do it. Can someone guide me ?

Numpy can't take floor of complex numbers, so instead of giving an error, it simply drops the imaginary part.So I think Numpy is working well

Ok, I thought it would be worth to throw at least a warning, that the imaginary part is dropped, similar to other functions.

Normal python throws an error, seems like we should probably follow suit, unless someone can think of a use case?

Yeah I think we should throw a TypeError.
Can I work on it ?

Personally i would even prefer a (2+2j)//2 = (1+1j), although it's not perfectly mathematically correct.

Not sure what is best, remainder is simply not implemented for complex (throws an error). And if we go to error, maybe we should deprecate first.

Of course you can work on it, it will require to dive a bit into the how ufuncs work and are generated, so it may not be quite trivial, also there may still be some discussion necessary of where we want to go. That does not need to stop you though.

"In the face of ambiguity, refuse the temptation to guess." suggests that it should be a TypeError.

@kaivu1999 - to address this, likely best would be to remove the complex types from even being generated in the floor_divide ufunc (note that divmod, remainder, and modf are already OK). Look in core/src/umath/loops.c.src, in stuff following line 2321 (likely just remove lines 2480--2500).

@mhvk yeah, you also have to adjust numpy/core/code_generators/generate_umath.py, but if we want to deprecate first, you will have to create a custom type resolver probably (touches additionally numpy/core/src/umath/ufunc_type_resolution.c).

@seberg - it seems the present behaviour should really just be considered a bug, and that for consistency with remainder and divmod, we should start raising an error.

Whether we might want different behaviour would seem a separate discussion.

Yeah, I am on it.
I have changed the code such, and now it shows:
`>>> a // 2

Traceback (most recent call last):
File "", line 1, in
TypeError: ufunc 'floor_divide' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
`
Shall I generate the pull request?

@kaivu1999 a pull request would be a good start. Please be sure to put Fixes #13236 in the first comment, which will cross reference the issue and the PR.

Doing floor division on both real and imaginary parts makes some sense if we document that Gaussian integers are the result. That wouldn't be consistent with Python though.

Was this page helpful?
0 / 5 - 0 ratings