Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

np.floor_divide drops imaginary part silently #13236

Closed
FranzForstmayr opened this issue Apr 1, 2019 · 13 comments · Fixed by #19135
Closed

np.floor_divide drops imaginary part silently #13236

FranzForstmayr opened this issue Apr 1, 2019 · 13 comments · Fixed by #19135

Comments

@FranzForstmayr
Copy link

FranzForstmayr commented Apr 1, 2019

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]

@kaivu1999
Copy link

kaivu1999 commented Apr 1, 2019

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 ?

@RuthAtem
Copy link

RuthAtem commented Apr 1, 2019

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

@FranzForstmayr
Copy link
Author

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

@seberg
Copy link
Member

seberg commented Apr 1, 2019

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

@kaivu1999
Copy link

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

@FranzForstmayr
Copy link
Author

FranzForstmayr commented Apr 1, 2019

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

@seberg
Copy link
Member

seberg commented Apr 1, 2019

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.

@mhvk
Copy link
Contributor

mhvk commented Apr 1, 2019

"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).

@seberg
Copy link
Member

seberg commented Apr 1, 2019

@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).

@mhvk
Copy link
Contributor

mhvk commented Apr 1, 2019

@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.

@kaivu1999
Copy link

kaivu1999 commented Apr 2, 2019

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?

@mattip
Copy link
Member

mattip commented Apr 2, 2019

@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.

@charris
Copy link
Member

charris commented Apr 2, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants