Repository: numba/numba

Issue:
.ptp() not @njit compilable anymore?
 
- [x] I have tried using the latest released version of Numba (most recent is
 visible in the change log (https://github.com/numba/numba/blob/master/CHANGE_LOG).
- [x] I have included below a minimal working reproducer (if you are unsure how
 to write one see http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports).
 

I cant pass numpy arrays like the following to an `njit` compiled function that contains` numpy.ptp()`.
Why is that ( I think here it says, that .ptp() is supported: https://numba.pydata.org/numba-doc/dev/reference/numpysupported.html)
 ```
a = [0.         ,0.         ,0.         ,0.         ,0.         ,0.
 ,0.         ,0.         ,0.00224828 ,0.00317533 ,0.00830591 ,0.00934349  
 ,0.80603907 ,0.80603907 ,0.80603907 ,0.80603907 ,0.80603907 ,0.94597275,
 1.,        1.,        1.,        1.,        1.,        1., 
 1.,       ]

import math
from numba import  prange
@nb.njit(nopython=True,parallel=True)
def anynan(array): 
    for i in prange(array.size):
        if math.isnan(array[i]):
            return True
    return False
@nb.njit
def scale_zero2one(x):
      
    x -= x.min()  
    x /= x.ptp()   
    if anynan(x):  
        x[np.isnan(x)] = 0               
    return x 

a = np.asarray(a,dtype=np.float32) 
print(scale_zero2one(a))
```


Discussion:
`np.ptp` is supported, but the `.ptp` method of array objects is not. Modifying your reproducer to define missing imports, define `a`, and use `np.ptp` instead results in a successful compilation:

```python
import math
import numpy as np
from numba import prange, njit


@njit(nopython=True, parallel=True)
def anynan(array):
    for i in prange(array.size):
        if math.isnan(array[i]):
            return True
    return False


@njit
def scale_zero2one(x):

    x -= x.min()
    x /= np.ptp(x)
    if anynan(x):
        x[np.isnan(x)] = 0
    return x


a = [1, 2, 3]

a = np.asarray(a, dtype=np.float32)
print(scale_zero2one(a))
```

Resolving patch:
diff --git a/numba/np/arraymath.py b/numba/np/arraymath.py
--- a/numba/np/arraymath.py
+++ b/numba/np/arraymath.py
@@ -1106,6 +1106,7 @@ def impl(val):
     return impl
 
 
+@overload_method(types.Array, 'ptp')
 @overload(np.ptp)
 def np_ptp(a):
 


Test patch:
diff --git a/numba/tests/test_array_reductions.py b/numba/tests/test_array_reductions.py
--- a/numba/tests/test_array_reductions.py
+++ b/numba/tests/test_array_reductions.py
@@ -128,6 +128,9 @@ def array_nanpercentile_global(arr, q):
 def array_ptp_global(a):
     return np.ptp(a)
 
+def array_ptp(a):
+    return a.ptp()
+
 def array_quantile_global(arr, q):
     return np.quantile(arr, q)
 
@@ -797,6 +800,17 @@ def a_variations():
         for a in a_variations():
             check(a)
 
+    def test_ptp_method(self):
+        # checks wiring of np.ndarray.ptp() only, `np.ptp` test above checks
+        # the actual alg
+        pyfunc = array_ptp
+        cfunc = jit(nopython=True)(pyfunc)
+
+        a = np.arange(10)
+        expected = pyfunc(a)
+        got = cfunc(a)
+        self.assertPreciseEqual(expected, got)
+
     def test_ptp_complex(self):
         pyfunc = array_ptp_global
         cfunc = jit(nopython=True)(pyfunc)