Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Wrong gradient values for unsigned int data #15207

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

Closed
arares opened this issue Dec 31, 2019 · 2 comments · Fixed by #15212
Closed

Wrong gradient values for unsigned int data #15207

arares opened this issue Dec 31, 2019 · 2 comments · Fixed by #15212

Comments

@arares
Copy link

arares commented Dec 31, 2019

Hi all,

The "numpy.gradient()" function returns wrong values for unsigned integer types. While the outputs are of np.float64 type, a part of the calculations seem to be done following the rules of the input data type (unsigned int). In our case, a negative gradient of -1 is wrapped around to a value of 255, -2 becomes 254, and so forth. The resulting gradient values can be non-integer because of some averaging taking place during the calculations.

I think the input data should first be cast to np.float64 and only then calculate the gradient.
It is useless to get correct digits after the comma, yet get huge errors before the comma.
Below you can find the code that highlights the erroneous behavior.

Best regards,

Andrei

Reproducing code example:

import numpy as np
a = np.array([[1, 1, 1], [2, 0, 1], [1, 1, 1]], dtype=np.uint8)
a  # Result:
# array([[1, 1, 1],
#        [2, 0, 1],
#        [1, 1, 1]], dtype=uint8)
dy, dx = np.gradient(a)
dy.dtype  # Result:
# dtype('float64')
dx.dtype  # Result:
# dtype('float64')
dy  # Result:
# array([[  1., 255.,   0.],
#        [  0.,   0.,   0.],
#        [255.,   1.,   0.]])
dx  # Result:
# array([[  0. ,   0. ,   0. ],
#        [254. , 127.5,   1. ],
#        [  0. ,   0. ,   0. ]])

Numpy/Python version information:

1.17.4 3.7.5 (default, Nov 7 2019, 10:50:52)
[GCC 8.3.0]

@WarrenWeckesser
Copy link
Member

@arares, thanks for reporting the issue.

The problem still exists in the development branch:

In [1]: import numpy as np                                                      

In [2]: x = np.array([5, 5, 4, 3, 2, 1, 1, 1], dtype=np.uint8)                  

In [3]: np.gradient(x)                                                          
Out[3]: array([  0. , 127.5, 127. , 127. , 127. , 127.5,   0. ,   0. ])

In [4]: np.__version__                                                          
Out[4]: '1.19.0.dev0+63ef78b'

@WarrenWeckesser
Copy link
Member

Another broken case:

In [62]: y = np.array([2.0, 3.0])

In [63]: x = np.array([-10, 127], dtype=np.int8)

In [64]: np.gradient(y, x)   # Incorrect.
Out[64]: array([-0.00840336, -0.00840336])

In [65]: np.gradient(y, x.astype(float))   # This gives the expected result.
Out[65]: array([0.00729927, 0.00729927])

WarrenWeckesser added a commit to WarrenWeckesser/numpy that referenced this issue Jan 1, 2020
In numpy.gradient, convert integer array inputs to float64 to avoid
unwanted modular arithmetic.

Closes numpygh-15207.
@WarrenWeckesser WarrenWeckesser added this to the 1.19.0 release milestone Jan 2, 2020
charris pushed a commit to charris/numpy that referenced this issue Jan 5, 2020
In numpy.gradient, convert integer array inputs to float64 to avoid
unwanted modular arithmetic.

Closes numpygh-15207.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants