internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: numpy/numpy

Issue:
1D ``np.linalg.norm`` not preserving input dtype?
I saw the [v1.14.0 release note](https://github.com/numpy/numpy/blob/master/doc/release/1.14.0-notes.rst#1d-nplinalgnorm-preserves-float-input-types-even-for-arbitrary-orders) saying:

> 1D np.linalg.norm preserves float input types, even for arbitrary orders

However, when I try the code on the release note, it does not behave as it says.

```py
>>> import numpy as np
>>> np.__version__
'1.14.0'
>>> f32 = np.float32([1, 2])
>>> np.linalg.norm(f32, 2.0).dtype
dtype('float32')
>>> np.linalg.norm(f32, 2.0001).dtype
dtype('float64')  # it should be float32 on numpy 1.14?
```


Discussion:
My fault in #9522 (351fe979580ab842cc5c04e1b616d3a64936a695). I think it does preserve `longdouble` types now, but I wasn't able to test that.

Maybe simplest to revert that part of the release note?
Culprit is the `1.0` on this line upcasting: https://github.com/numpy/numpy/commit/351fe979580ab842cc5c04e1b616d3a64936a695#diff-6858bbac5c5c59bdddf245c69d6a547cR2206

Replacing it with `1` or `np.reciprocal` should solve the problem.

Resolving patch:
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -2277,7 +2277,7 @@ def norm(x, ord=None, axis=None, keepdims=False):
             return abs(x).min(axis=axis, keepdims=keepdims)
         elif ord == 0:
             # Zero norm
-            return (x != 0).astype(float).sum(axis=axis, keepdims=keepdims)
+            return (x != 0).astype(x.real.dtype).sum(axis=axis, keepdims=keepdims)
         elif ord == 1:
             # special case for speedup
             return add.reduce(abs(x), axis=axis, keepdims=keepdims)
@@ -2292,7 +2292,9 @@ def norm(x, ord=None, axis=None, keepdims=False):
                 raise ValueError("Invalid norm order for vectors.")
             absx = abs(x)
             absx **= ord
-            return add.reduce(absx, axis=axis, keepdims=keepdims) ** (1.0 / ord)
+            ret = add.reduce(absx, axis=axis, keepdims=keepdims)
+            ret **= (1 / ord)
+            return ret
     elif len(axis) == 2:
         row_axis, col_axis = axis
         row_axis = normalize_axis_index(row_axis, nd)


Test patch:
Repository: numpy/numpy

Issue:
Undocumented behaviour of `np.concatenate` with `axis=None`
```
>>> a = np.array([[1,2,],[3,4]])
>>> b = a + 10
>>> np.concatenate((a, b), axis=0)

array([[ 1,  2],
       [ 3,  4],
       [11, 12],
       [13, 14]])
>>> np.concatenate((a, b), axis=1)

array([[ 1,  2, 11, 12],
       [ 3,  4, 13, 14]])
>>> np.concatenate((a, b), axis=None)
array([ 1,  2,  3,  4, 11, 12, 13, 14])
```



Discussion:
Hey @eric-wieser, I would like to try working on this issue.  Will be my first time contributing to open-source, so need to go through all the numpy guides on contributing first.  But wanted to go ahead and speak up for something.  Can you add me as a contributor and assignee on this issue?  Is that the correct procedure?
Thanks
No need to add you as a contributor - if you haven't already, take a look at [our contribution guide](https://github.com/numpy/numpy/blob/master/CONTRIBUTING.md#contributing-code).

For something as simple as documentation, where there's nothing to test, you should be able to just edit the file (`add_newdocs.py` or similar) right in github, which will automatically do the right thing of creating a fork and feature branch for you to work in.

In practice numpy seems not to use assignees much.
  

Resolving patch:
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -1232,7 +1232,8 @@ def luf(lamdaexpr, *args, **kwargs):
         The arrays must have the same shape, except in the dimension
         corresponding to `axis` (the first, by default).
     axis : int, optional
-        The axis along which the arrays will be joined.  Default is 0.
+        The axis along which the arrays will be joined.  If axis is None,
+        arrays are flattened before use.  Default is 0.
     out : ndarray, optional
         If provided, the destination to place the result. The shape must be
         correct, matching that of what concatenate would have returned if no
@@ -1276,6 +1277,8 @@ def luf(lamdaexpr, *args, **kwargs):
     >>> np.concatenate((a, b.T), axis=1)
     array([[1, 2, 5],
            [3, 4, 6]])
+    >>> np.concatenate((a, b), axis=None)
+    array([1, 2, 3, 4, 5, 6])
 
     This function will not preserve masking of MaskedArray inputs.
 


Test patch:
Repository: numpy/numpy

Issue:
loadtxt documentation
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.loadtxt.html

says

"converters : dict, optional A dictionary mapping column number to a function that will convert that column to a float. "

Should it not be a function converting to whatever the target dtype is (e.g. it might be complex)?



Discussion:
Sounds right, can you open a pull request with the suggested changes?

Resolving patch:
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -797,22 +797,23 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
         The string used to separate values. For backwards compatibility, byte
         strings will be decoded as 'latin1'. The default is whitespace.
     converters : dict, optional
-        A dictionary mapping column number to a function that will convert
-        that column to a float.  E.g., if column 0 is a date string:
-        ``converters = {0: datestr2num}``.  Converters can also be used to
-        provide a default value for missing data (but see also `genfromtxt`):
-        ``converters = {3: lambda s: float(s.strip() or 0)}``.  Default: None.
+        A dictionary mapping column number to a function that will parse the
+        column string into the desired value.  E.g., if column 0 is a date
+        string: ``converters = {0: datestr2num}``.  Converters can also be
+        used to provide a default value for missing data (but see also
+        `genfromtxt`): ``converters = {3: lambda s: float(s.strip() or 0)}``.
+        Default: None.
     skiprows : int, optional
         Skip the first `skiprows` lines; default: 0.
     usecols : int or sequence, optional
         Which columns to read, with 0 being the first. For example,
-        usecols = (1,4,5) will extract the 2nd, 5th and 6th columns.
+        ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.
         The default, None, results in all columns being read.
 
         .. versionchanged:: 1.11.0
             When a single column has to be read it is possible to use
             an integer instead of a tuple. E.g ``usecols = 3`` reads the
-            fourth column the same way as `usecols = (3,)`` would.
+            fourth column the same way as ``usecols = (3,)`` would.
     unpack : bool, optional
         If True, the returned array is transposed, so that arguments may be
         unpacked using ``x, y, z = loadtxt(...)``.  When used with a structured
@@ -827,7 +828,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
         Encoding used to decode the inputfile. Does not apply to input streams.
         The special value 'bytes' enables backward compatibility workarounds
         that ensures you receive byte arrays as results if possible and passes
-        latin1 encoded strings to converters. Override this value to receive
+        'latin1' encoded strings to converters. Override this value to receive
         unicode arrays and pass strings as input to converters.  If set to None
         the system default is used. The default value is 'bytes'.
 


Test patch:
Repository: numpy/numpy

Issue:
Mistake in documentation of numpy.gradient
Under "Notes" the second line in the second equation should read 
                \\beta h_{d}-\\gamma h_{s}=1 \\\\


Discussion:
You should be able to edit it [in-browser here](https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L712) - patches welcome!

Resolving patch:
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -839,7 +839,7 @@ def gradient(f, *varargs, **kwargs):
         \\left\\{
             \\begin{array}{r}
                 \\alpha+\\beta+\\gamma=0 \\\\
-                -\\beta h_{d}+\\gamma h_{s}=1 \\\\
+                \\beta h_{d}-\\gamma h_{s}=1 \\\\
                 \\beta h_{d}^{2}+\\gamma h_{s}^{2}=0
             \\end{array}
         \\right.


Test patch:
Repository: numpy/numpy

Issue:
np.flatnonzero doesn't cast to ndarray
Thus, it fails for lists and such:

    >>> np.flatnonzero([1,2,3])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File ".../python3.6/site-packages/numpy/core/numeric.py", line 859, in flatnonzero
        return a.ravel().nonzero()[0]
    AttributeError: 'list' object has no attribute 'ravel'


Discussion:

Resolving patch:
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -829,12 +829,12 @@ def flatnonzero(a):
     """
     Return indices that are non-zero in the flattened version of a.
 
-    This is equivalent to a.ravel().nonzero()[0].
+    This is equivalent to np.nonzero(np.ravel(a))[0].
 
     Parameters
     ----------
-    a : ndarray
-        Input array.
+    a : array_like
+        Input data.
 
     Returns
     -------
@@ -862,7 +862,7 @@ def flatnonzero(a):
     array([-2, -1,  1,  2])
 
     """
-    return a.ravel().nonzero()[0]
+    return np.nonzero(np.ravel(a))[0]
 
 
 _mode_from_name_dict = {'v': 0,


Test patch:
Repository: numpy/numpy

Issue:
np.histogram gives confusing error message when NaN is encountered
If one tries to do `np.histogram([1,2,3,4,np.nan])`, then an error message is thrown:
`ValueError: range parameter must be finite.`

This message is somewhat confusing, because I had to open up the source code of `histogram` to see that `mn` and `mx`, which were determined from `a.min()` and `a.max()`, were NaN because of NaN's in the input data.

Is it possible to change it to something like "input data contains NaN, which is not supported"?

Python version: 3.6
numpy version: 1.13.3



Discussion:
Same message in 1.15

Note that input containing NaN _is_ supported, but only if a range parameter is specified. The same behavior can be seen for infinities too - so perhaps `"autodetected range of [{min}, {max}] is not finite"`

A patch should be fairly straightforward
I'd like to make this patch. Can I go ahead and submit a PR?

Resolving patch:
diff --git a/numpy/lib/histograms.py b/numpy/lib/histograms.py
--- a/numpy/lib/histograms.py
+++ b/numpy/lib/histograms.py
@@ -219,18 +219,20 @@ def _get_outer_edges(a, range):
     """
     if range is not None:
         first_edge, last_edge = range
+        if first_edge > last_edge:
+            raise ValueError(
+                'max must be larger than min in range parameter.')
+        if not (np.isfinite(first_edge) and np.isfinite(last_edge)):
+            raise ValueError(
+                "supplied range of [{}, {}] is not finite".format(first_edge, last_edge))
     elif a.size == 0:
         # handle empty arrays. Can't determine range, so use 0-1.
         first_edge, last_edge = 0, 1
     else:
         first_edge, last_edge = a.min(), a.max()
-
-    if first_edge > last_edge:
-        raise ValueError(
-            'max must be larger than min in range parameter.')
-    if not (np.isfinite(first_edge) and np.isfinite(last_edge)):
-        raise ValueError(
-            'range parameter must be finite.')
+        if not (np.isfinite(first_edge) and np.isfinite(last_edge)):
+            raise ValueError(
+                "autodetected range of [{}, {}] is not finite".format(first_edge, last_edge))
 
     # expand empty range to avoid divide by zero
     if first_edge == last_edge:


Test patch:
Repository: numpy/numpy

Issue:
DOC/BUG: np.sum supports generators, unlike the other reduction helpers

```python
>>> np.sum(a for a in range(10))
45
>>> np.prod(a for a in range(10))
<generator object <genexpr> at 0x0000023BAF7ED1A8>
```

Generators are not considered `array_like`, so the result for `sum` does not match the documentation.

Introduced in a13aad3ac33b629f3e696b4d4d5dbf4b5605d567


Discussion:
This also happens for `np.[any|all|min|max]`. I fixed it in #10661. Take a look.

Resolving patch:
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -1881,6 +1881,12 @@ def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
     if keepdims is not np._NoValue:
         kwargs['keepdims'] = keepdims
     if isinstance(a, _gentype):
+        # 2018-02-25, 1.15.0
+        warnings.warn(
+            "Calling np.sum(generator) is deprecated, and in the future will give a different result. "
+            "Use np.sum(np.from_iter(generator)) or the python sum builtin instead.",
+            DeprecationWarning, stacklevel=2)
+
         res = _sum_(a)
         if out is not None:
             out[...] = res


Test patch:
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -481,5 +481,11 @@ def test_bincount_minlength(self):
         self.assert_deprecated(lambda: np.bincount([1, 2, 3], minlength=None))
 
 
+class TestGeneratorSum(_DeprecationTestCase):
+    # 2018-02-25, 1.15.0
+    def test_generator_sum(self):
+        self.assert_deprecated(np.sum, args=((i for i in range(5)),))
+
+
 if __name__ == "__main__":
     run_module_suite()
Repository: numpy/numpy

Issue:
a.size and np.prod(a.shape) are not equivalent
The documentation of `ndarray.size` claims that `a.size` is equivalent to `np.prod(a.shape)`. While they do return the same value, they return different types and therefore are not equivalent.

```python
a = np.zeros((2, 2))

type(a.size)
# returns <class 'int'>

type(np.prod(a.shape))
# returns <class 'numpy.int64'>
```

Continuing the calculations using `np.prod(a.shape)` can therefore lead to integer overflows.

I guess `np.prod(a.shape)` cannot be changed to return a `<class 'int'>` instance, and `a.size` should certainly not be changed to return a `<class 'numpy.int64'>` instance, so probably the only solution is to update the documentation to reflect that these two are not fully equivalent.

I'd be happy to make pull-request to update the documentation accordingly.


Discussion:
I somewhat doubt that replacing "equivalent" with "equal" will actually help much, but seems like a small documentation improvement, so sounds good. Can you create a quick PR for it?
Maybe to be clear, the only difference between the two is that `np.prod` effectively calls `np.asarray` on the tuple and that converts the integer to non-python type.
@seberg I don't think replacing _equivalent_ with _equal_ is sufficient. Instead, the documentation should explicitly state the difference explicitly.

Resolving patch:
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -3060,9 +3060,17 @@ def luf(lamdaexpr, *args, **kwargs):
     """
     Number of elements in the array.
 
-    Equivalent to ``np.prod(a.shape)``, i.e., the product of the array's
+    Equal to ``np.prod(a.shape)``, i.e., the product of the array's
     dimensions.
 
+    Notes
+    -----
+    `a.size` returns a standard arbitrary precision Python integer. This 
+    may not be the case with other methods of obtaining the same value
+    (like the suggested ``np.prod(a.shape)``, which returns an instance
+    of ``np.int_``), and may be relevant if the value is used further in
+    calculations that may overflow a fixed size integer type.
+
     Examples
     --------
     >>> x = np.zeros((3, 5, 2), dtype=np.complex128)


Test patch:
Repository: numpy/numpy

Issue:
Legacy 1.13 printing broken for 0d arrays
Code to trigger the error:
```python
>>> import numpy as np
>>> np.__version__
'1.14.2'
>>> np.array2string(np.array(1.0))
'1.'
>>> np.set_printoptions(legacy='1.13')
>>> np.array2string(np.array(1.0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[...]/numpy/core/arrayprint.py", line 616, in array2string
    return style(a.item())
TypeError: object() takes no parameters
```
Same error with 1.14.1 and 1.14.0.

Since `style` is just an alias for `np._NoValue` the code effectively calls (or instantiates, depending on the code version) `_NoValue(1.0)`, which is not valid.
I saw that there was a recent change in `_globals.py` that makes `_NoValue` an instance instead of a class, but it has no `__call__`, so unless I'm missing something, it won't work either.


Discussion:
Yep, this is a bug. Thoughts @ahaldane? Can we really afford a fourth 1.14.x release?
There are a few other nits that could go in to a 1.14.3. Maybe I can try making a release as @charris suggested...

Resolving patch:
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -647,6 +647,9 @@ def array2string(a, max_line_width=None, precision=None,
     options.update(overrides)
 
     if options['legacy'] == '1.13':
+        if style is np._NoValue:
+            style = repr
+
         if a.shape == () and not a.dtype.names:
             return style(a.item())
     elif style is not np._NoValue:


Test patch:
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -491,6 +491,8 @@ def test_0d_arrays(self):
                                          np.array(1.), style=repr)
         # but not in legacy mode
         np.array2string(np.array(1.), style=repr, legacy='1.13')
+        # gh-10934 style was broken in legacy mode, check it works
+        np.array2string(np.array(1.), legacy='1.13')
 
     def test_float_spacing(self):
         x = np.array([1., 2., 3.])
Repository: numpy/numpy

Issue:
Legacy 1.13 printing broken for 0d arrays
Code to trigger the error:
```python
>>> import numpy as np
>>> np.__version__
'1.14.2'
>>> np.array2string(np.array(1.0))
'1.'
>>> np.set_printoptions(legacy='1.13')
>>> np.array2string(np.array(1.0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[...]/numpy/core/arrayprint.py", line 616, in array2string
    return style(a.item())
TypeError: object() takes no parameters
```
Same error with 1.14.1 and 1.14.0.

Since `style` is just an alias for `np._NoValue` the code effectively calls (or instantiates, depending on the code version) `_NoValue(1.0)`, which is not valid.
I saw that there was a recent change in `_globals.py` that makes `_NoValue` an instance instead of a class, but it has no `__call__`, so unless I'm missing something, it won't work either.


Discussion:
Yep, this is a bug. Thoughts @ahaldane? Can we really afford a fourth 1.14.x release?
There are a few other nits that could go in to a 1.14.3. Maybe I can try making a release as @charris suggested...

Resolving patch:
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -612,6 +612,9 @@ def array2string(a, max_line_width=None, precision=None,
     options.update(overrides)
 
     if options['legacy'] == '1.13':
+        if style is np._NoValue:
+            style = repr
+
         if a.shape == () and not a.dtype.names:
             return style(a.item())
     elif style is not np._NoValue:


Test patch:
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -488,6 +488,8 @@ def test_0d_arrays(self):
                                          np.array(1.), style=repr)
         # but not in legacy mode
         np.array2string(np.array(1.), style=repr, legacy='1.13')
+        # gh-10934 style was broken in legacy mode, check it works
+        np.array2string(np.array(1.), legacy='1.13')
 
     def test_float_spacing(self):
         x = np.array([1., 2., 3.])
Repository: numpy/numpy

Issue:
Copy and deepcopy of np.ma.masked returns np.ma.array()
I would expect that copy or deepcopy of `np.ma.masked` would give me the same object, but this doesn't appear to be the case:
```
In [9]: copy.deepcopy(np.ma.masked)
Out[9]: 
masked_array(data=--,
             mask=True,
       fill_value=1e+20,
            dtype=float64)

In [10]: copy.copy(np.ma.masked)
Out[10]: 
masked_array(data=--,
             mask=True,
       fill_value=1e+20,
            dtype=float64)

In [11]: type(copy.deepcopy(np.ma.masked))
Out[11]: numpy.ma.core.MaskedArray

In [12]: type(np.ma.masked)
Out[12]: numpy.ma.core.MaskedConstant

In [13]: np.__version__
Out[13]: '1.14.2'
```


Discussion:
Should be an easy fix - just implement `__copy__` and `__deepcopy__` on `MaskedConstant`
I am newbie and would like to take a stab at it if nobody is working on it already

Resolving patch:
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -6317,6 +6317,12 @@ def copy(self, *args, **kwargs):
         # precedent for this with `np.bool_` scalars.
         return self
 
+    def __copy__(self):
+        return self
+		
+    def __deepcopy__(self, memo):
+        return self
+
     def __setattr__(self, attr, value):
         if not self.__has_singleton():
             # allow the singleton to be initialized


Test patch:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -4826,6 +4826,16 @@ def test_copy(self):
             np.ma.masked.copy() is np.ma.masked,
             np.True_.copy() is np.True_)
 
+    def test__copy(self):
+        import copy
+        assert_(
+            copy.copy(np.ma.masked) is np.ma.masked)
+
+    def test_deepcopy(self):
+        import copy
+        assert_(
+            copy.deepcopy(np.ma.masked) is np.ma.masked)
+
     def test_immutable(self):
         orig = np.ma.masked
         assert_raises(np.ma.core.MaskError, operator.setitem, orig, (), 1)
Repository: numpy/numpy

Issue:
`np.random.permutation` & `np.random.shuffle` are slow.
`np.random.permutation(x)` is the same as `x[np.random.permutation(x.shape[0])]` semantically if `x` is an array. Why the latter is so much faster than the former?

```python
    x = np.random.rand(50000, 2)
    %timeit x.take(np.random.permutation(x.shape[0]), axis=0)
    # 1.02 ms
    %timeit x[np.random.permutation(x.shape[0])]
    # 1.75 ms
    %timeit np.random.permutation(x)
    # 34.1 ms
    %timeit np.random.shuffle(x)
    # 34.2 ms
```


Discussion:
`shuffle` has a general path for any like-like object and a fat path for 1-d NumPy Arrays.

From shuffle:
```
        if type(x) is np.ndarray and x.ndim == 1 and x.size:
            # Fast, statically typed path: shuffle the underlying buffer.
            # Only for non-empty, 1d objects of class ndarray (subclasses such
            # as MaskedArrays may not support this approach).
```



Resolving patch:
diff --git a/benchmarks/benchmarks/bench_random.py b/benchmarks/benchmarks/bench_random.py
--- a/benchmarks/benchmarks/bench_random.py
+++ b/benchmarks/benchmarks/bench_random.py
@@ -65,3 +65,18 @@ def time_randint_slow(self, name):
         high = self.high[name]
         np.random.randint(0, high + 1, size=10**5, dtype=name)
 
+
+class Permutation(Benchmark):
+    def setup(self):
+        self.n = 10000
+        self.a_1d = np.random.random_sample(self.n)
+        self.a_2d = np.random.random_sample((self.n, 2))
+    
+    def time_permutation_1d(self):
+        np.random.permutation(self.a_1d)
+
+    def time_permutation_2d(self):
+        np.random.permutation(self.a_2d)        
+
+    def time_permutation_int(self):
+        np.random.permutation(self.n)


Test patch: