Repository: scipy/scipy

Issue:
Cannot create sparse matrix from size_t indexes
If I try to create a sparse matrix in COOrdinate format with row and column indexes in `size_t` type, `coo_matrix` will throw an error as it seems it tries to cast `size_t` to `float64`.

The following code illustrates the problem:
```python
import numpy as np
import ctypes
from scipy.sparse import coo_matrix

nrow = 10**4
ncol = 10**5
nnz = 10**6
np.random.seed(1)
row_id = np.random.randint(nrow, size=nnz).astype(ctypes.c_size_t)
col_id = np.random.randint(ncol, size=nnz).astype(ctypes.c_size_t)
vals = np.random.normal(size=nnz)

sp_matrix = coo_matrix((vals, (row_id, col_id)))
```
Throws:
```
Traceback (most recent call last):

  File "<ipython-input-1-5bbb7c9f9698>", line 13, in <module>
    sp_matrix = coo_matrix((vals, (row_id, col_id)))

  File "/home/david/anaconda3/lib/python3.6/site-packages/scipy/sparse/coo.py", line 150, in __init__
    self._shape = check_shape((M, N))

  File "/home/david/anaconda3/lib/python3.6/site-packages/scipy/sparse/sputils.py", line 281, in check_shape
    new_shape = tuple(operator.index(arg) for arg in args)

  File "/home/david/anaconda3/lib/python3.6/site-packages/scipy/sparse/sputils.py", line 281, in <genexpr>
    new_shape = tuple(operator.index(arg) for arg in args)

TypeError: 'numpy.float64' object cannot be interpreted as an integer
```

Adding the shape will however allow to construct this matrix:
```python
coo_matrix((vals, (row_id, col_id)), shape=(nrow, ncol))
```
```
<10000x100000 sparse matrix of type '<class 'numpy.float64'>'
	with 1000000 stored elements in COOrdinate format>
```

The problem is not present when the indexes are of `int` or `long` type:
```python
coo_matrix((vals, (row_id.astype(ctypes.c_long), col_id.astype(ctypes.c_long))))
```
```
<10000x100000 sparse matrix of type '<class 'numpy.float64'>'
	with 1000000 stored elements in COOrdinate format>
```


Discussion:
The index needs to be signed integer, size_t is unsigned.

The error message is perhaps confusing, but it's because in casting float64 is the next common type uint64 and signed integers can be cast to.

**EDIT**: ok, the shape check should not fail like this nevertheless

Resolving patch:
diff --git a/scipy/sparse/coo.py b/scipy/sparse/coo.py
--- a/scipy/sparse/coo.py
+++ b/scipy/sparse/coo.py
@@ -18,6 +18,8 @@
                       get_index_dtype, downcast_intp_index, check_shape,
                       check_reshape_kwargs)
 
+import operator
+
 
 class coo_matrix(_data_matrix, _minmax_mixin):
     """
@@ -145,8 +147,8 @@ def __init__(self, arg1, shape=None, dtype=None, copy=False):
                     if len(row) == 0 or len(col) == 0:
                         raise ValueError('cannot infer dimensions from zero '
                                          'sized index arrays')
-                    M = np.max(row) + 1
-                    N = np.max(col) + 1
+                    M = operator.index(np.max(row)) + 1
+                    N = operator.index(np.max(col)) + 1
                     self._shape = check_shape((M, N))
                 else:
                     # Use 2 steps to ensure shape has length 2.


Test patch: