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

Issue:
Bug in stats.fisher_exact
A problem with stats.fisher_exact was reported on stackoverflow:
    http://stackoverflow.com/questions/19548854/python-scipy-stats-module-valueerror-axis-entry-is-out-of-bounds

The culprit appears to be this line:
    https://github.com/scipy/scipy/blob/master/scipy/stats/stats.py#L2633
I assume that `np.max(pexact, pmode)` should be `np.maximum(pexact, pmode)`.  

As it is now, `pmode` is being passed to `np.max()` as its `axis` argument.  Usually `pmode` is less than 1, so the `axis` value is truncated to 0 and an error is not generated.  For the special case reported in the Stack Overflow question, `stats.fisher_exact([[1,2],[9,84419233]])`, `pmode` is 1.00000001738, so an error is raised.



Discussion:
the change to np.maximum looks correct to me, but I also don't know the algorithm.

pmode shouldn't be really above one since it's a probability.

I don't think this bug could have produced numbers that are much wrong, since the condition only holds if pexact and pmode are almost the same.

I also don't know the algorithm.  But will happily prepare a PR if you think this doesn't need further investigation.

Why the `abs` in the denominator of https://github.com/scipy/scipy/blob/master/scipy/stats/stats.py#L2583? Both `pmode` and `pexact` should be positive.

Why the `float` in the numerator? Both `pmode` and `pexact` are results of `hypergeom.pmf`, so should both be `float`, so their difference should be `float`. 

@rgommers: Since this seems to be "your" code, can you comment?

IIRC that was due to a bug in `stats.hypergeom`, where p-value could be negative. Fixed in 0.14.0, so `abs` can be removed from denominator. 

`max` --> `maximum` fix looks right to me.

``float`: don't remember. Could be useless, or also a bug fix. Anyway, looks to me like it can be removed now.


Resolving patch:
diff --git a/scipy/stats/stats.py b/scipy/stats/stats.py
--- a/scipy/stats/stats.py
+++ b/scipy/stats/stats.py
@@ -2580,7 +2580,7 @@ def binary_search(n, n1, n2, side):
         pmode = hypergeom.pmf(mode, n1 + n2, n1, n)
 
         epsilon = 1 - 1e-4
-        if float(np.abs(pexact - pmode)) / np.abs(np.max(pexact, pmode)) <= 1 - epsilon:
+        if np.abs(pexact - pmode) / np.maximum(pexact, pmode) <= 1 - epsilon:
             return oddsratio, 1.
 
         elif c[0,0] < mode:


Test patch:
diff --git a/scipy/stats/tests/test_stats.py b/scipy/stats/tests/test_stats.py
--- a/scipy/stats/tests/test_stats.py
+++ b/scipy/stats/tests/test_stats.py
@@ -450,6 +450,11 @@ def test_less_greater(self):
             res.append(stats.fisher_exact(table, alternative="greater")[1])
             assert_allclose(res, pval, atol=0, rtol=1e-7)
 
+    def test_gh3014(self):
+        # check if issue #3014 has been fixed.
+        # before, this would have risen a ValueError
+        odds, pvalue = stats.fisher_exact([[1, 2], [9, 84419233]])
+
 
 class TestCorrSpearmanr(TestCase):
     """ W.II.D. Compute a correlation matrix on all the variables.
Repository: scipy/scipy

Issue:
interp2d is weird (Trac #1364)
_Original ticket http://projects.scipy.org/scipy/ticket/1364 on 2011-01-16 by trac user bubla, assigned to unknown._

The interp2d function either crashes or gives strange results.
Consider the following code:

```
import scipy as sp
import scipy.interpolate

rand = sp.rand(2,3)
#array([[ 0.84793638,  0.8332837 ,  0.31432397],
#       [ 0.30853293,  0.6814913 ,  0.73636099]])
x = sp.arange(2)
y = sp.arange(3)
rand_i = sp.interpolate.interp2d(x,y,rand)
rand_i(0, 0)
# returns array([ 0.84793638])
rand_i(1, 1)
# returns array([ 0.30853293]) - that's weird, isn't it?
```

Moreover, if you try to interpolate a larger array:
- 50 x 50 array is OK
- 20 x 50 fails with a strange error (something about B-spline coefficients, which is strange since linear interpolation is supposed to be used)
- 30 x 50 crashes ipython without any messages

Could you take a look at this?



Discussion:
_@pv wrote on 2011-01-16_

If you do

```
rand_i = sp.interpolate.interp2d(x,y,rand.T)
```

it works as expected. Nevertheless, the current behavior is wrong -- it should raise an error and not fail silently like this.

_trac user bubla wrote on 2011-01-17_

You are right that the transposition of the array solves the issue (I think that I will submit some docstring patch)

However, the second issue (the "strange error") is still a problem.
Just try

```
for i in range(20):
    rand = sp.rand(20,30)
    sp.interpolate.interp2d(sp.arange(20), sp.arange(30), rand.T)
```

and you are very likely to encounter the error I have talked about (I am unlucky enough to operate with a data set requiring interpolation that is affected by this error)

Title changed from `interp2d is weirdb` to `interp2d is weird` by trac user bubla on 2011-01-17


Resolving patch:
diff --git a/scipy/interpolate/interpolate.py b/scipy/interpolate/interpolate.py
--- a/scipy/interpolate/interpolate.py
+++ b/scipy/interpolate/interpolate.py
@@ -178,6 +178,11 @@ def __init__(self, x, y, z, kind='linear', copy=True, bounds_error=False,
 
         rectangular_grid = (z.size == len(x) * len(y))
         if rectangular_grid:
+            if z.ndim == 2:
+                if z.shape != (len(y), len(x)):
+                    raise ValueError("When on a regular grid with x.size = m "
+                                     "and y.size = n, if z.ndim == 2, then z "
+                                     "must have shape (n, m)")
             if not np.all(x[1:] >= x[:-1]):
                 j = np.argsort(x)
                 x = x[j]


Test patch:
diff --git a/scipy/interpolate/tests/test_interpolate.py b/scipy/interpolate/tests/test_interpolate.py
--- a/scipy/interpolate/tests/test_interpolate.py
+++ b/scipy/interpolate/tests/test_interpolate.py
@@ -72,7 +72,7 @@ def test_interp2d_linear(self):
     def test_interp2d_bounds(self):
         x = np.linspace(0, 1, 5)
         y = np.linspace(0, 2, 7)
-        z = x[:,None]**2 + y[None,:]
+        z = x[None, :]**2 + y[:, None]
 
         ix = np.linspace(-1, 3, 31)
         iy = np.linspace(-1, 3, 33)
Repository: scipy/scipy

Issue:
BUG: linalg.hessenberg broken (wrong results)
The function `scipy.linalg.hessenberg` computes wrong factorizations. Minimal example:

``` python
import numpy
from scipy.linalg import hessenberg

A = numpy.eye(3)
A[-1,0] = 2
H, Q = hessenberg(A, calc_q=True)
print(A - Q.dot(H.dot(Q.T)))
```

yields

```
[[ 0. -2.  0.]
 [ 0.  0.  0.]
 [ 2.  0.  0.]]
```

but should be zero. I observed the bug in 0.12.0 and it's still in current master.



Discussion:

Resolving patch:
diff --git a/scipy/linalg/decomp.py b/scipy/linalg/decomp.py
--- a/scipy/linalg/decomp.py
+++ b/scipy/linalg/decomp.py
@@ -820,7 +820,7 @@ def hessenberg(a, calc_q=False, overwrite_a=False, check_finite=True):
         raise ValueError('expected square matrix')
     overwrite_a = overwrite_a or (_datacopied(a1, a))
     gehrd,gebal = get_lapack_funcs(('gehrd','gebal'), (a1,))
-    ba, lo, hi, pivscale, info = gebal(a1, permute=1, overwrite_a=overwrite_a)
+    ba, lo, hi, pivscale, info = gebal(a1, permute=0, overwrite_a=overwrite_a)
     if info < 0:
         raise ValueError('illegal value in %d-th argument of internal gebal '
                                                     '(hessenberg)' % -info)


Test patch:
diff --git a/scipy/linalg/tests/test_decomp.py b/scipy/linalg/tests/test_decomp.py
--- a/scipy/linalg/tests/test_decomp.py
+++ b/scipy/linalg/tests/test_decomp.py
@@ -1714,6 +1714,12 @@ def test_simple2(self):
         h,q = hessenberg(a,calc_q=1)
         assert_array_almost_equal(dot(transp(q),dot(a,q)),h)
 
+    def test_simple3(self):
+        a = np.eye(3)
+        a[-1, 0] = 2
+        h, q = hessenberg(a, calc_q=1)
+        assert_array_almost_equal(dot(transp(q), dot(a, q)), h)
+
     def test_random(self):
         n = 20
         for k in range(2):
Repository: scipy/scipy

Issue:
dendogram(orientation='foo') 
I looks like dendogram does not check if the orientation is a legal string and this leads to an  unintended exception down the line. 



Discussion:
Indeed. And it should be easy to fix.


Resolving patch:
diff --git a/scipy/cluster/hierarchy.py b/scipy/cluster/hierarchy.py
--- a/scipy/cluster/hierarchy.py
+++ b/scipy/cluster/hierarchy.py
@@ -2114,6 +2114,10 @@ def dendrogram(Z, p=30, truncate_mode=None, color_threshold=None,
     #         pre-order traversal.
     Z = np.asarray(Z, order='c')
 
+    if orientation not in ["top", "left", "bottom", "right"]:
+        raise ValueError("orientation must be one of 'top', 'left', "
+                         "'bottom', or 'right'")
+
     is_valid_linkage(Z, throw=True, name='Z')
     Zs = Z.shape
     n = Zs[0] + 1


Test patch:
diff --git a/scipy/cluster/tests/test_hierarchy.py b/scipy/cluster/tests/test_hierarchy.py
--- a/scipy/cluster/tests/test_hierarchy.py
+++ b/scipy/cluster/tests/test_hierarchy.py
@@ -1433,6 +1433,10 @@ def test_dendrogram_single_linkage_tdist(self):
         leaves = R["leaves"]
         self.assertEqual(leaves, [2, 5, 1, 0, 3, 4])
 
+    def test_valid_orientation(self):
+        Z = linkage(_ytdist, 'single')
+        assert_raises(ValueError, dendrogram, Z, orientation="foo")
+
     @dec.skipif(not have_matplotlib)
     def test_dendrogram_plot(self):
         # Tests dendrogram plotting.
Repository: scipy/scipy

Issue:
Inconsistent exceptions raised by scipy.io.loadmat
Depending on whether loadmat is passed a non-existent filename with or without the ".mat" extension, the exception raised chages from IOError to FileNotFoundError.  I believe an easy patch would be to simply change `scipy.io.matlab.mio._open_file` to re-raise rather than raise `IOError(e)`.



Discussion:

Resolving patch:
diff --git a/scipy/io/matlab/mio.py b/scipy/io/matlab/mio.py
--- a/scipy/io/matlab/mio.py
+++ b/scipy/io/matlab/mio.py
@@ -24,8 +24,11 @@ def _open_file(file_like, appendmat):
         except IOError as e:
             if appendmat and not file_like.endswith('.mat'):
                 file_like += '.mat'
-                return open(file_like, 'rb')
-            raise IOError(e)
+                try:
+                    return open(file_like, 'rb')
+                except IOError:
+                    pass  # Rethrow the original exception.
+            raise
     # not a string - maybe file-like object
     try:
         file_like.read(0)


Test patch:
Repository: scipy/scipy

Issue:
KroghInterpolator doesn't pass through points
I tried interpolating samples from a monotonic function:

```
x = [0, 234,468,702,936,1170,1404,2340,3744,6084,8424,13104,60000]
offset_cdf = array([-0.95      , -0.86114777, -0.8147762 , -0.64072425, -0.48002351,
       -0.34925329, -0.26503107, -0.13148093, -0.12988833, -0.12979296,
       -0.12973574, -0.08582937,  0.05])

f = KroghInterpolator(x, offset_cdf)
```

The first points are interpolated fine:

```
In [63]: f(x[0]) - offset_cdf[0]
Out[63]: 0.0

In [65]: f(x[5]) - offset_cdf[5]
Out[65]: -3.3306690738754696e-16
```

but the interpolator doesn't pass through the last ones:

```
In [66]: f(x[8]) - offset_cdf[8]
Out[66]: 1399.8986518615748

In [67]: f(x[9]) - offset_cdf[9]
Out[67]: 24411.38732329784

In [68]: f(x[11]) - offset_cdf[11]
Out[68]: -68246.638977765731

In [69]: f(x[12]) - offset_cdf[12]
Out[69]: 25511149.696103323
```

AFAIK interpolators are required to pass through the interpolation points. This also appears in the docs (http://docs.scipy.org/doc/scipy-0.13.0/reference/generated/scipy.interpolate.KroghInterpolator.html).



Discussion:
The reason seems to be that the passed-in arrays is integer type, and `KroghInterpolator._evaluate` does not cast it to floats as it should.

Workaround: `x = array(x, dtype=float)`

Using the example above, when changing line 320 in `polyint.py` to

```
            w = np.asarray(x, dtype=self.dtype) - self.xi[k-1]
```

I get

```
In[5]: [f(x[i]) - offset_cdf[i] for i in range(13)]
Out[5]: 
[0.0,
 0.0,
 0.0,
 0.0,
 0.0,
 -3.3306690738754696e-16,
 -4.9960036108132044e-16,
 -2.1649348980190553e-15,
 -8.5265128291212022e-14,
 -1.1400269617212189e-11,
 -3.6732317187926355e-10,
 2.2627944948339085e-08,
 -0.050000000000000003]
```

I'm still surprised to see such a large deviation for the last point ...  Is this acceptable / expected?  Should I prepare this as PR, or do we need to investigate further?


Resolving patch:
diff --git a/scipy/interpolate/polyint.py b/scipy/interpolate/polyint.py
--- a/scipy/interpolate/polyint.py
+++ b/scipy/interpolate/polyint.py
@@ -317,7 +317,7 @@ def _evaluate(self, x):
         p = np.zeros((len(x), self.r), dtype=self.dtype)
         p += self.c[0,np.newaxis,:]
         for k in range(1, self.n):
-            w = x - self.xi[k-1]
+            w = np.asarray(x, dtype=self.dtype) - self.xi[k-1]
             pi = w*pi
             p += pi[:,np.newaxis] * self.c[k]
         return p


Test patch:
Repository: scipy/scipy

Issue:
typo in scipy.cluster.hierarchy.linkage documentation
The `scipy.cluster.hierarchy.linkage` documentation contains repetitive text [see here](https://github.com/scipy/scipy/blob/97e93bd0ef24b9d1f59cfba4fd0b540f348cb4c9/scipy/cluster/hierarchy.py#L541). I'll submit a pull request to fix this.



Discussion:

Resolving patch:
diff --git a/scipy/cluster/hierarchy.py b/scipy/cluster/hierarchy.py
--- a/scipy/cluster/hierarchy.py
+++ b/scipy/cluster/hierarchy.py
@@ -539,7 +539,7 @@ def linkage(y, method='single', metric='euclidean'):
         for all points :math:`i` and :math:`j` where :math:`|u|`
         and :math:`|v|` are the cardinalities of clusters :math:`u`
         and :math:`v`, respectively. This is also called the UPGMA
-        algorithm. This is called UPGMA.
+        algorithm.
 
       * method='weighted' assigns
 


Test patch:
Repository: scipy/scipy

Issue:
misleading documentation of scipy.optimize.curve_fit
The documentation says that sigma is the relative weights vector but actually, it is the inverse of the relative weights right? 



Discussion:
This seems to have been debated earlier https://github.com/scipy/scipy/pull/448#issuecomment-14025241 although I personally do not understand the issues or tradeoffs involved.

I think the best would be to add the formulas in the notes, so it's unambiguous, something like
`min ((y - f(x, p)) / sigma)**2   w.r.t. p`

sigma is inverse weights in standard WLS

I agree with josef-pkt, not all of us (the users) are familiar with the terminology for the Weighted Least Squares symbols (I didn't even know the meaning of WLS) and when I saw the the documentation I definitely thought that sigma meant something else and had to take a look at the code after obtaining unexpected results. I think a formula would be clear for every one. 

@josef-pkt wrote:

> I think the best would be to add the formulas in the notes, so it's unambiguous...

:+1:


Resolving patch:
diff --git a/scipy/optimize/minpack.py b/scipy/optimize/minpack.py
--- a/scipy/optimize/minpack.py
+++ b/scipy/optimize/minpack.py
@@ -473,8 +473,10 @@ def curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, **kw):
         can be determined using introspection, otherwise a ValueError
         is raised).
     sigma : None or M-length sequence, optional
-        If not None, these values are used as weights in the
-        least-squares problem.
+        If not None, the uncertainties in the ydata array. These are used as
+        weights in the least-squares problem
+        i.e. minimising ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )``
+        If None, the uncertainties are assumed to be 1.
     absolute_sigma : bool, optional
         If False, `sigma` denotes relative weights of the data points.
         The returned covariance matrix `pcov` is based on *estimated*


Test patch:
Repository: scipy/scipy

Issue:
Inconsistent doc for integrate.romb
The doc string states:

```
y : array_like

    A vector of 2**k + 1 equally-spaced samples of a function.

dx : array_like, optional

    The sample spacing. Default is 1.
```

If the samples are equally spaced, why is `dx` array_like?



Discussion:

Resolving patch:
diff --git a/scipy/integrate/quadrature.py b/scipy/integrate/quadrature.py
--- a/scipy/integrate/quadrature.py
+++ b/scipy/integrate/quadrature.py
@@ -426,7 +426,7 @@ def romb(y, dx=1.0, axis=-1, show=False):
     ----------
     y : array_like
         A vector of ``2**k + 1`` equally-spaced samples of a function.
-    dx : array_like, optional
+    dx : float, optional
         The sample spacing. Default is 1.
     axis : int, optional
         The axis along which to integrate. Default is -1 (last axis).


Test patch:
Repository: scipy/scipy

Issue:
optimize.leastsq() documentation should mention it does not work with NaNs
In the documentation of the `leastsq` function, there should be a sentence regarding the handling `NaNs`.  Otherwise, the fitting might fail to calculate the parameters just because the data contain null/nan values, and the user will be clueless as to why this has happened.



Discussion:

Resolving patch:
diff --git a/scipy/optimize/minpack.py b/scipy/optimize/minpack.py
--- a/scipy/optimize/minpack.py
+++ b/scipy/optimize/minpack.py
@@ -268,7 +268,8 @@ def leastsq(func, x0, args=(), Dfun=None, full_output=0,
     ----------
     func : callable
         should take at least one (possibly length N vector) argument and
-        returns M floating point numbers.
+        returns M floating point numbers. It must not return NaNs or
+        fitting might fail.
     x0 : ndarray
         The starting estimate for the minimization.
     args : tuple


Test patch:
Repository: scipy/scipy

Issue:
In knn, calling to query with k>n returns weird results
When calling the query function of KNN with k > n (number of nodes in the tree), one receives in the distances array values of inf for the subsequent supposedly "k nearest neighbors (after k>n)".
I believe the algorithm should return the list of neighbors up to n and no more.

I hope I've been clear enough.
You can repeat the bug by inserting n points in the tree, and making a query with k > n.

Let me know if I haven't been clear enough.
Thanks a lot for the great job guys!



Discussion:
Are you sure the bugreport belongs to scipy and not to scikit-learn? I couldn't find a single occurrence of `knn` in scipy's code.

I think this is about `scipy.spatial.KDTree`, which does this:

```
from scipy.spatial import KDTree
import numpy as np
x = np.random.rand(5, 2)
t = KDTree(x)
print(t.query([0.5, 0.5], k=10))
# -> (array([ 0.11168922,  0.12782096,  0.2687416 ,  0.35849166,  0.41559252,
#               inf,         inf,         inf,         inf,         inf]),
# array([3, 4, 1, 2, 0, 5, 5, 5, 5, 5]))
```

The behavior is documented and changing it has backward compat issues, however.

Maybe it would be more obvious if the "missing neighbours" is replaced with something like "if k > n"?


Resolving patch:
diff --git a/scipy/spatial/kdtree.py b/scipy/spatial/kdtree.py
--- a/scipy/spatial/kdtree.py
+++ b/scipy/spatial/kdtree.py
@@ -421,8 +421,9 @@ def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
         d : array of floats
             The distances to the nearest neighbors.
             If x has shape tuple+(self.m,), then d has shape tuple if
-            k is one, or tuple+(k,) if k is larger than one.  Missing
-            neighbors are indicated with infinite distances.  If k is None,
+            k is one, or tuple+(k,) if k is larger than one. Missing
+            neighbors (e.g. when k > n or distance_upper_bound is
+            given) are indicated with infinite distances.  If k is None,
             then d is an object array of shape tuple, containing lists
             of distances. In either case the hits are sorted by distance
             (nearest first).


Test patch:
Repository: scipy/scipy

Issue:
Scipy.Spatial.KdTree (Query) Return Type?
Return types on the KDTree query are inconsistent with the documentation in that, if k=1 the returns are numpy scalars, but the docs suggest the return will be an array.  Obviously with k=2 the return type is an array.

Is this the intended behavior?

``` python
import scipy.spatial

coordinates = [ (3,4), (5,6), (50,1), (10,10) , (10,11), (5,3) ]

kdt = scipy.spatial.KDTree(coordinates, leafsize=10)

di, ni =  kdt.query(coordinates[2], k=1)
print type(ni), type(di)
#<type 'numpy.int64'> <type 'numpy.float64'> 
di, ni =  kdt.query(coordinates[2], k=2)
print type(ni), type(di)
#<type 'numpy.ndarray'> <type 'numpy.ndarray'>
```



Discussion:
> Is this the intended behavior?

Yes I found unit tests that check these cases explicitly.
https://github.com/scipy/scipy/blob/maintenance/0.14.x/scipy/spatial/tests/test_kdtree.py#L119
I guess this should be explained in the docstrings.


Resolving patch:
diff --git a/scipy/spatial/kdtree.py b/scipy/spatial/kdtree.py
--- a/scipy/spatial/kdtree.py
+++ b/scipy/spatial/kdtree.py
@@ -418,7 +418,7 @@ def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
 
         Returns
         -------
-        d : array of floats
+        d : float or array of floats
             The distances to the nearest neighbors.
             If x has shape tuple+(self.m,), then d has shape tuple if
             k is one, or tuple+(k,) if k is larger than one.  Missing
@@ -426,7 +426,7 @@ def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
             then d is an object array of shape tuple, containing lists
             of distances. In either case the hits are sorted by distance
             (nearest first).
-        i : array of integers
+        i : integer or array of integers
             The locations of the neighbors in self.data. i is the same
             shape as d.
 
@@ -469,6 +469,8 @@ def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
         >>> pts = np.array([[0, 0], [2.1, 2.9]])
         >>> tree.query(pts)
         (array([ 2.        ,  0.14142136]), array([ 0, 13]))
+        >>> tree.query(pts[0])
+        (2.0, 0)
 
         """
         x = np.asarray(x)


Test patch:
Repository: scipy/scipy

Issue:
Misleading error message in eigsh: k must be between 1 and rank(A)-1
In `scipy/sparse/linalg/eigen/arpack/arpack.py` line 1487 of scipy 0.13.3:

```
n = A.shape[0]

if k <= 0 or k >= n:
    raise ValueError("k must be between 1 and rank(A)-1")
```

The expected meaning of rank should be that of http://en.wikipedia.org/wiki/Rank_(linear_algebra) captured in http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.linalg.matrix_rank.html for example.

However, in this implementation, the notion of "rank" is equated with the dimension of the array. 

A conceptual mismatch with a potential for debugging headaches.  



Discussion:
> The expected meaning of rank should be that of http://en.wikipedia.org/wiki/Rank_(linear_algebra)

In numpy I think that `rank` means [`np.rank`](https://github.com/numpy/numpy/blob/maintenance/1.9.x/numpy/core/fromnumeric.py#L2451) whereas the rank you expect is [`np.linalg.matrix_rank`](http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.linalg.matrix_rank.html).  I agree that this is confusing and weird.

**Edit**: Now I see that in the context of that function, it means neither of those two things.  In fact the error message has been [changed](https://github.com/scipy/scipy/blob/master/scipy/sparse/linalg/eigen/arpack/arpack.py#L1487) to use `ndim` instead of `rank`, but this is still wrong.  What it actually means is the [order](https://proofwiki.org/wiki/Definition:Matrix/Square_Matrix/Order) of the square input matrix, as also used in http://en.wikipedia.org/wiki/Square_matrix.  In any case the docs should be changed because `ndim` is just wrong.


Resolving patch:
diff --git a/scipy/sparse/linalg/eigen/arpack/arpack.py b/scipy/sparse/linalg/eigen/arpack/arpack.py
--- a/scipy/sparse/linalg/eigen/arpack/arpack.py
+++ b/scipy/sparse/linalg/eigen/arpack/arpack.py
@@ -1497,7 +1497,8 @@ def eigsh(A, k=6, M=None, sigma=None, which='LM', v0=None,
     n = A.shape[0]
 
     if k <= 0 or k >= n:
-        raise ValueError("k must be between 1 and ndim(A)-1")
+        raise ValueError("k must be between 1 and the order of the "
+                         "square input matrix.")
 
     if sigma is None:
         A = _aslinearoperator_with_dtype(A)


Test patch: