We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Support SciPy 1.0
SciPy 1.0 released. It has some compatibility breaks in `scipy.sparse`. We need to fix implementations or tests.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cupyx/scipy/sparse/compressed.py`
Content:
```
1 import numpy
2 try:
3     import scipy.sparse
4     scipy_available = True
5 except ImportError:
6     scipy_available = False
7 
8 import cupy
9 from cupy import core
10 from cupy.creation import basic
11 from cupy import cusparse
12 from cupyx.scipy.sparse import base
13 from cupyx.scipy.sparse import data as sparse_data
14 from cupyx.scipy.sparse import util
15 
16 
17 class _compressed_sparse_matrix(sparse_data._data_matrix):
18 
19     _compress_getitem_kern = core.ElementwiseKernel(
20         'T d, S ind, int32 minor', 'raw T answer',
21         'if (ind == minor) atomicAdd(&answer[0], d);',
22         'compress_getitem')
23 
24     _compress_getitem_complex_kern = core.ElementwiseKernel(
25         'T real, T imag, S ind, int32 minor',
26         'raw T answer_real, raw T answer_imag',
27         '''
28         if (ind == minor) {
29           atomicAdd(&answer_real[0], real);
30           atomicAdd(&answer_imag[0], imag);
31         }
32         ''',
33         'compress_getitem_complex')
34 
35     def __init__(self, arg1, shape=None, dtype=None, copy=False):
36         if shape is not None and len(shape) != 2:
37             raise ValueError(
38                 'Only two-dimensional sparse arrays are supported.')
39 
40         if base.issparse(arg1):
41             x = arg1.asformat(self.format)
42             data = x.data
43             indices = x.indices
44             indptr = x.indptr
45 
46             if arg1.format != self.format:
47                 # When formats are differnent, all arrays are already copied
48                 copy = False
49 
50             if shape is None:
51                 shape = arg1.shape
52 
53             has_canonical_format = x.has_canonical_format
54         elif util.isshape(arg1):
55             m, n = arg1
56             m, n = int(m), int(n)
57             data = basic.zeros(0, dtype if dtype else 'd')
58             indices = basic.zeros(0, 'i')
59             indptr = basic.zeros(self._swap(m, n)[0] + 1, dtype='i')
60             # shape and copy argument is ignored
61             shape = (m, n)
62             copy = False
63             has_canonical_format = True
64 
65         elif scipy_available and scipy.sparse.issparse(arg1):
66             # Convert scipy.sparse to cupyx.scipy.sparse
67             x = arg1.asformat(self.format)
68             data = cupy.array(x.data)
69             indices = cupy.array(x.indices, dtype='i')
70             indptr = cupy.array(x.indptr, dtype='i')
71             copy = False
72 
73             if shape is None:
74                 shape = arg1.shape
75             has_canonical_format = x.has_canonical_format
76 
77         elif isinstance(arg1, tuple) and len(arg1) == 3:
78             data, indices, indptr = arg1
79             if not (base.isdense(data) and data.ndim == 1 and
80                     base.isdense(indices) and indices.ndim == 1 and
81                     base.isdense(indptr) and indptr.ndim == 1):
82                 raise ValueError(
83                     'data, indices, and indptr should be 1-D')
84 
85             if len(data) != len(indices):
86                 raise ValueError('indices and data should have the same size')
87 
88             has_canonical_format = False
89 
90         elif base.isdense(arg1):
91             if arg1.ndim > 2:
92                 raise TypeError('expected dimension <= 2 array or matrix')
93             elif arg1.ndim == 1:
94                 arg1 = arg1[None]
95             elif arg1.ndim == 0:
96                 arg1 = arg1[None, None]
97             data, indices, indptr = self._convert_dense(arg1)
98             copy = False
99             if shape is None:
100                 shape = arg1.shape
101 
102             has_canonical_format = True
103 
104         else:
105             raise ValueError(
106                 'Unsupported initializer format')
107 
108         if dtype is None:
109             dtype = data.dtype
110         else:
111             dtype = numpy.dtype(dtype)
112 
113         if dtype != 'f' and dtype != 'd' and dtype != 'F' and dtype != 'D':
114             raise ValueError(
115                 'Only float32, float64, complex64 and complex128 '
116                 'are supported')
117 
118         data = data.astype(dtype, copy=copy)
119         sparse_data._data_matrix.__init__(self, data)
120 
121         self.indices = indices.astype('i', copy=copy)
122         self.indptr = indptr.astype('i', copy=copy)
123 
124         if shape is None:
125             shape = self._swap(len(indptr) - 1, int(indices.max()) + 1)
126 
127         major, minor = self._swap(*shape)
128         if len(indptr) != major + 1:
129             raise ValueError('index pointer size (%d) should be (%d)'
130                              % (len(indptr), major + 1))
131 
132         self._descr = cusparse.MatDescriptor.create()
133         self._shape = shape
134         self._has_canonical_format = has_canonical_format
135 
136     def _with_data(self, data):
137         return self.__class__(
138             (data, self.indices.copy(), self.indptr.copy()), shape=self.shape)
139 
140     def _convert_dense(self, x):
141         raise NotImplementedError
142 
143     def _swap(self, x, y):
144         raise NotImplementedError
145 
146     def _add_sparse(self, other, alpha, beta):
147         raise NotImplementedError
148 
149     def _add(self, other, lhs_negative, rhs_negative):
150         if cupy.isscalar(other):
151             if other == 0:
152                 if lhs_negative:
153                     return -self
154                 else:
155                     return self.copy()
156             else:
157                 raise NotImplementedError(
158                     'adding a nonzero scalar to a sparse matrix is not '
159                     'supported')
160         elif base.isspmatrix(other):
161             alpha = -1 if lhs_negative else 1
162             beta = -1 if rhs_negative else 1
163             return self._add_sparse(other, alpha, beta)
164         elif base.isdense(other):
165             if lhs_negative:
166                 if rhs_negative:
167                     return -self.todense() - other
168                 else:
169                     return other - self.todense()
170             else:
171                 if rhs_negative:
172                     return self.todense() - other
173                 else:
174                     return self.todense() + other
175         else:
176             return NotImplemented
177 
178     def __add__(self, other):
179         return self._add(other, False, False)
180 
181     def __radd__(self, other):
182         return self._add(other, False, False)
183 
184     def __sub__(self, other):
185         return self._add(other, False, True)
186 
187     def __rsub__(self, other):
188         return self._add(other, True, False)
189 
190     def __getitem__(self, slices):
191         if isinstance(slices, tuple):
192             slices = list(slices)
193         elif isinstance(slices, list):
194             slices = list(slices)
195             if all([isinstance(s, int) for s in slices]):
196                 slices = [slices]
197         else:
198             slices = [slices]
199 
200         ellipsis = -1
201         n_ellipsis = 0
202         for i, s in enumerate(slices):
203             if s is None:
204                 raise IndexError('newaxis is not supported')
205             elif s is Ellipsis:
206                 ellipsis = i
207                 n_ellipsis += 1
208         if n_ellipsis > 0:
209             ellipsis_size = self.ndim - (len(slices) - 1)
210             slices[ellipsis:ellipsis + 1] = [slice(None)] * ellipsis_size
211 
212         if len(slices) == 2:
213             row, col = slices
214         elif len(slices) == 1:
215             row, col = slices[0], slice(None)
216         else:
217             raise IndexError('invalid number of indices')
218 
219         major, minor = self._swap(row, col)
220         major_size, minor_size = self._swap(*self._shape)
221         if numpy.isscalar(major):
222             i = int(major)
223             if i < 0:
224                 i += major_size
225             if not (0 <= i < major_size):
226                 raise IndexError('index out of bounds')
227             if numpy.isscalar(minor):
228                 j = int(minor)
229                 if j < 0:
230                     j += minor_size
231                 if not (0 <= j < minor_size):
232                     raise IndexError('index out of bounds')
233                 return self._get_single(i, j)
234             elif minor == slice(None):
235                 return self._get_major_slice(slice(i, i + 1))
236         elif isinstance(major, slice):
237             if minor == slice(None):
238                 return self._get_major_slice(major)
239 
240         raise ValueError('unsupported indexing')
241 
242     def _get_single(self, major, minor):
243         start = self.indptr[major]
244         end = self.indptr[major + 1]
245         answer = cupy.zeros((), self.dtype)
246         data = self.data[start:end]
247         indices = self.indices[start:end]
248         if self.dtype.kind == 'c':
249             self._compress_getitem_complex_kern(
250                 data.real, data.imag, indices, minor, answer.real, answer.imag)
251         else:
252             self._compress_getitem_kern(
253                 data, indices, minor, answer)
254         return answer[()]
255 
256     def _get_major_slice(self, major):
257         major_size, minor_size = self._swap(*self._shape)
258         # major.indices cannot be used because scipy.sparse behaves differently
259         major_start = major.start
260         major_stop = major.stop
261         major_step = major.step
262         if major_start is None:
263             major_start = 0
264         if major_stop is None:
265             major_stop = major_size
266         if major_step is None:
267             major_step = 1
268         if major_start < 0:
269             major_start += major_size
270         if major_stop < 0:
271             major_stop += major_size
272 
273         if major_step != 1:
274             raise ValueError('slicing with step != 1 not supported')
275 
276         if not (0 <= major_start <= major_size and
277                 0 <= major_stop <= major_size and
278                 major_start <= major_stop):
279             raise IndexError('index out of bounds')
280 
281         start = self.indptr[major_start]
282         stop = self.indptr[major_stop]
283         data = self.data[start:stop]
284         indptr = self.indptr[major_start:major_stop + 1] - start
285         indices = self.indices[start:stop]
286 
287         shape = self._swap(len(indptr) - 1, minor_size)
288         return self.__class__(
289             (data, indices, indptr), shape=shape, dtype=self.dtype, copy=False)
290 
291     @property
292     def has_canonical_format(self):
293         return self._has_canonical_format
294 
295     def get_shape(self):
296         """Returns the shape of the matrix.
297 
298         Returns:
299             tuple: Shape of the matrix.
300         """
301         return self._shape
302 
303     def getnnz(self, axis=None):
304         """Returns the number of stored values, including explicit zeros.
305 
306         Args:
307             axis: Not supported yet.
308 
309         Returns:
310             int: The number of stored values.
311 
312         """
313         if axis is None:
314             return self.data.size
315         else:
316             raise ValueError
317 
318     # TODO(unno): Implement sorted_indices
319 
320     def sum_duplicates(self):
321         if self._has_canonical_format:
322             return
323         if self.data.size == 0:
324             self._has_canonical_format = True
325             return
326         coo = self.tocoo()
327         coo.sum_duplicates()
328         self.__init__(coo.asformat(self.format))
329         self._has_canonical_format = True
330
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cupyx/scipy/sparse/compressed.py b/cupyx/scipy/sparse/compressed.py
--- a/cupyx/scipy/sparse/compressed.py
+++ b/cupyx/scipy/sparse/compressed.py
@@ -269,13 +269,13 @@
             major_start += major_size
         if major_stop < 0:
             major_stop += major_size
+        major_start = max(min(major_start, major_size), 0)
+        major_stop = max(min(major_stop, major_size), 0)
 
         if major_step != 1:
             raise ValueError('slicing with step != 1 not supported')
 
-        if not (0 <= major_start <= major_size and
-                0 <= major_stop <= major_size and
-                major_start <= major_stop):
+        if not (major_start <= major_stop):
             raise IndexError('index out of bounds')
 
         start = self.indptr[major_start]

{"golden_diff": "diff --git a/cupyx/scipy/sparse/compressed.py b/cupyx/scipy/sparse/compressed.py\n--- a/cupyx/scipy/sparse/compressed.py\n+++ b/cupyx/scipy/sparse/compressed.py\n@@ -269,13 +269,13 @@\n             major_start += major_size\n         if major_stop < 0:\n             major_stop += major_size\n+        major_start = max(min(major_start, major_size), 0)\n+        major_stop = max(min(major_stop, major_size), 0)\n \n         if major_step != 1:\n             raise ValueError('slicing with step != 1 not supported')\n \n-        if not (0 <= major_start <= major_size and\n-                0 <= major_stop <= major_size and\n-                major_start <= major_stop):\n+        if not (major_start <= major_stop):\n             raise IndexError('index out of bounds')\n \n         start = self.indptr[major_start]\n", "issue": "Support SciPy 1.0\nSciPy 1.0 released. It has some compatibility breaks in `scipy.sparse`. We need to fix implementations or tests.\n", "before_files": [{"content": "import numpy\ntry:\n    import scipy.sparse\n    scipy_available = True\nexcept ImportError:\n    scipy_available = False\n\nimport cupy\nfrom cupy import core\nfrom cupy.creation import basic\nfrom cupy import cusparse\nfrom cupyx.scipy.sparse import base\nfrom cupyx.scipy.sparse import data as sparse_data\nfrom cupyx.scipy.sparse import util\n\n\nclass _compressed_sparse_matrix(sparse_data._data_matrix):\n\n    _compress_getitem_kern = core.ElementwiseKernel(\n        'T d, S ind, int32 minor', 'raw T answer',\n        'if (ind == minor) atomicAdd(&answer[0], d);',\n        'compress_getitem')\n\n    _compress_getitem_complex_kern = core.ElementwiseKernel(\n        'T real, T imag, S ind, int32 minor',\n        'raw T answer_real, raw T answer_imag',\n        '''\n        if (ind == minor) {\n          atomicAdd(&answer_real[0], real);\n          atomicAdd(&answer_imag[0], imag);\n        }\n        ''',\n        'compress_getitem_complex')\n\n    def __init__(self, arg1, shape=None, dtype=None, copy=False):\n        if shape is not None and len(shape) != 2:\n            raise ValueError(\n                'Only two-dimensional sparse arrays are supported.')\n\n        if base.issparse(arg1):\n            x = arg1.asformat(self.format)\n            data = x.data\n            indices = x.indices\n            indptr = x.indptr\n\n            if arg1.format != self.format:\n                # When formats are differnent, all arrays are already copied\n                copy = False\n\n            if shape is None:\n                shape = arg1.shape\n\n            has_canonical_format = x.has_canonical_format\n        elif util.isshape(arg1):\n            m, n = arg1\n            m, n = int(m), int(n)\n            data = basic.zeros(0, dtype if dtype else 'd')\n            indices = basic.zeros(0, 'i')\n            indptr = basic.zeros(self._swap(m, n)[0] + 1, dtype='i')\n            # shape and copy argument is ignored\n            shape = (m, n)\n            copy = False\n            has_canonical_format = True\n\n        elif scipy_available and scipy.sparse.issparse(arg1):\n            # Convert scipy.sparse to cupyx.scipy.sparse\n            x = arg1.asformat(self.format)\n            data = cupy.array(x.data)\n            indices = cupy.array(x.indices, dtype='i')\n            indptr = cupy.array(x.indptr, dtype='i')\n            copy = False\n\n            if shape is None:\n                shape = arg1.shape\n            has_canonical_format = x.has_canonical_format\n\n        elif isinstance(arg1, tuple) and len(arg1) == 3:\n            data, indices, indptr = arg1\n            if not (base.isdense(data) and data.ndim == 1 and\n                    base.isdense(indices) and indices.ndim == 1 and\n                    base.isdense(indptr) and indptr.ndim == 1):\n                raise ValueError(\n                    'data, indices, and indptr should be 1-D')\n\n            if len(data) != len(indices):\n                raise ValueError('indices and data should have the same size')\n\n            has_canonical_format = False\n\n        elif base.isdense(arg1):\n            if arg1.ndim > 2:\n                raise TypeError('expected dimension <= 2 array or matrix')\n            elif arg1.ndim == 1:\n                arg1 = arg1[None]\n            elif arg1.ndim == 0:\n                arg1 = arg1[None, None]\n            data, indices, indptr = self._convert_dense(arg1)\n            copy = False\n            if shape is None:\n                shape = arg1.shape\n\n            has_canonical_format = True\n\n        else:\n            raise ValueError(\n                'Unsupported initializer format')\n\n        if dtype is None:\n            dtype = data.dtype\n        else:\n            dtype = numpy.dtype(dtype)\n\n        if dtype != 'f' and dtype != 'd' and dtype != 'F' and dtype != 'D':\n            raise ValueError(\n                'Only float32, float64, complex64 and complex128 '\n                'are supported')\n\n        data = data.astype(dtype, copy=copy)\n        sparse_data._data_matrix.__init__(self, data)\n\n        self.indices = indices.astype('i', copy=copy)\n        self.indptr = indptr.astype('i', copy=copy)\n\n        if shape is None:\n            shape = self._swap(len(indptr) - 1, int(indices.max()) + 1)\n\n        major, minor = self._swap(*shape)\n        if len(indptr) != major + 1:\n            raise ValueError('index pointer size (%d) should be (%d)'\n                             % (len(indptr), major + 1))\n\n        self._descr = cusparse.MatDescriptor.create()\n        self._shape = shape\n        self._has_canonical_format = has_canonical_format\n\n    def _with_data(self, data):\n        return self.__class__(\n            (data, self.indices.copy(), self.indptr.copy()), shape=self.shape)\n\n    def _convert_dense(self, x):\n        raise NotImplementedError\n\n    def _swap(self, x, y):\n        raise NotImplementedError\n\n    def _add_sparse(self, other, alpha, beta):\n        raise NotImplementedError\n\n    def _add(self, other, lhs_negative, rhs_negative):\n        if cupy.isscalar(other):\n            if other == 0:\n                if lhs_negative:\n                    return -self\n                else:\n                    return self.copy()\n            else:\n                raise NotImplementedError(\n                    'adding a nonzero scalar to a sparse matrix is not '\n                    'supported')\n        elif base.isspmatrix(other):\n            alpha = -1 if lhs_negative else 1\n            beta = -1 if rhs_negative else 1\n            return self._add_sparse(other, alpha, beta)\n        elif base.isdense(other):\n            if lhs_negative:\n                if rhs_negative:\n                    return -self.todense() - other\n                else:\n                    return other - self.todense()\n            else:\n                if rhs_negative:\n                    return self.todense() - other\n                else:\n                    return self.todense() + other\n        else:\n            return NotImplemented\n\n    def __add__(self, other):\n        return self._add(other, False, False)\n\n    def __radd__(self, other):\n        return self._add(other, False, False)\n\n    def __sub__(self, other):\n        return self._add(other, False, True)\n\n    def __rsub__(self, other):\n        return self._add(other, True, False)\n\n    def __getitem__(self, slices):\n        if isinstance(slices, tuple):\n            slices = list(slices)\n        elif isinstance(slices, list):\n            slices = list(slices)\n            if all([isinstance(s, int) for s in slices]):\n                slices = [slices]\n        else:\n            slices = [slices]\n\n        ellipsis = -1\n        n_ellipsis = 0\n        for i, s in enumerate(slices):\n            if s is None:\n                raise IndexError('newaxis is not supported')\n            elif s is Ellipsis:\n                ellipsis = i\n                n_ellipsis += 1\n        if n_ellipsis > 0:\n            ellipsis_size = self.ndim - (len(slices) - 1)\n            slices[ellipsis:ellipsis + 1] = [slice(None)] * ellipsis_size\n\n        if len(slices) == 2:\n            row, col = slices\n        elif len(slices) == 1:\n            row, col = slices[0], slice(None)\n        else:\n            raise IndexError('invalid number of indices')\n\n        major, minor = self._swap(row, col)\n        major_size, minor_size = self._swap(*self._shape)\n        if numpy.isscalar(major):\n            i = int(major)\n            if i < 0:\n                i += major_size\n            if not (0 <= i < major_size):\n                raise IndexError('index out of bounds')\n            if numpy.isscalar(minor):\n                j = int(minor)\n                if j < 0:\n                    j += minor_size\n                if not (0 <= j < minor_size):\n                    raise IndexError('index out of bounds')\n                return self._get_single(i, j)\n            elif minor == slice(None):\n                return self._get_major_slice(slice(i, i + 1))\n        elif isinstance(major, slice):\n            if minor == slice(None):\n                return self._get_major_slice(major)\n\n        raise ValueError('unsupported indexing')\n\n    def _get_single(self, major, minor):\n        start = self.indptr[major]\n        end = self.indptr[major + 1]\n        answer = cupy.zeros((), self.dtype)\n        data = self.data[start:end]\n        indices = self.indices[start:end]\n        if self.dtype.kind == 'c':\n            self._compress_getitem_complex_kern(\n                data.real, data.imag, indices, minor, answer.real, answer.imag)\n        else:\n            self._compress_getitem_kern(\n                data, indices, minor, answer)\n        return answer[()]\n\n    def _get_major_slice(self, major):\n        major_size, minor_size = self._swap(*self._shape)\n        # major.indices cannot be used because scipy.sparse behaves differently\n        major_start = major.start\n        major_stop = major.stop\n        major_step = major.step\n        if major_start is None:\n            major_start = 0\n        if major_stop is None:\n            major_stop = major_size\n        if major_step is None:\n            major_step = 1\n        if major_start < 0:\n            major_start += major_size\n        if major_stop < 0:\n            major_stop += major_size\n\n        if major_step != 1:\n            raise ValueError('slicing with step != 1 not supported')\n\n        if not (0 <= major_start <= major_size and\n                0 <= major_stop <= major_size and\n                major_start <= major_stop):\n            raise IndexError('index out of bounds')\n\n        start = self.indptr[major_start]\n        stop = self.indptr[major_stop]\n        data = self.data[start:stop]\n        indptr = self.indptr[major_start:major_stop + 1] - start\n        indices = self.indices[start:stop]\n\n        shape = self._swap(len(indptr) - 1, minor_size)\n        return self.__class__(\n            (data, indices, indptr), shape=shape, dtype=self.dtype, copy=False)\n\n    @property\n    def has_canonical_format(self):\n        return self._has_canonical_format\n\n    def get_shape(self):\n        \"\"\"Returns the shape of the matrix.\n\n        Returns:\n            tuple: Shape of the matrix.\n        \"\"\"\n        return self._shape\n\n    def getnnz(self, axis=None):\n        \"\"\"Returns the number of stored values, including explicit zeros.\n\n        Args:\n            axis: Not supported yet.\n\n        Returns:\n            int: The number of stored values.\n\n        \"\"\"\n        if axis is None:\n            return self.data.size\n        else:\n            raise ValueError\n\n    # TODO(unno): Implement sorted_indices\n\n    def sum_duplicates(self):\n        if self._has_canonical_format:\n            return\n        if self.data.size == 0:\n            self._has_canonical_format = True\n            return\n        coo = self.tocoo()\n        coo.sum_duplicates()\n        self.__init__(coo.asformat(self.format))\n        self._has_canonical_format = True\n", "path": "cupyx/scipy/sparse/compressed.py"}], "after_files": [{"content": "import numpy\ntry:\n    import scipy.sparse\n    scipy_available = True\nexcept ImportError:\n    scipy_available = False\n\nimport cupy\nfrom cupy import core\nfrom cupy.creation import basic\nfrom cupy import cusparse\nfrom cupyx.scipy.sparse import base\nfrom cupyx.scipy.sparse import data as sparse_data\nfrom cupyx.scipy.sparse import util\n\n\nclass _compressed_sparse_matrix(sparse_data._data_matrix):\n\n    _compress_getitem_kern = core.ElementwiseKernel(\n        'T d, S ind, int32 minor', 'raw T answer',\n        'if (ind == minor) atomicAdd(&answer[0], d);',\n        'compress_getitem')\n\n    _compress_getitem_complex_kern = core.ElementwiseKernel(\n        'T real, T imag, S ind, int32 minor',\n        'raw T answer_real, raw T answer_imag',\n        '''\n        if (ind == minor) {\n          atomicAdd(&answer_real[0], real);\n          atomicAdd(&answer_imag[0], imag);\n        }\n        ''',\n        'compress_getitem_complex')\n\n    def __init__(self, arg1, shape=None, dtype=None, copy=False):\n        if shape is not None and len(shape) != 2:\n            raise ValueError(\n                'Only two-dimensional sparse arrays are supported.')\n\n        if base.issparse(arg1):\n            x = arg1.asformat(self.format)\n            data = x.data\n            indices = x.indices\n            indptr = x.indptr\n\n            if arg1.format != self.format:\n                # When formats are differnent, all arrays are already copied\n                copy = False\n\n            if shape is None:\n                shape = arg1.shape\n\n            has_canonical_format = x.has_canonical_format\n        elif util.isshape(arg1):\n            m, n = arg1\n            m, n = int(m), int(n)\n            data = basic.zeros(0, dtype if dtype else 'd')\n            indices = basic.zeros(0, 'i')\n            indptr = basic.zeros(self._swap(m, n)[0] + 1, dtype='i')\n            # shape and copy argument is ignored\n            shape = (m, n)\n            copy = False\n            has_canonical_format = True\n\n        elif scipy_available and scipy.sparse.issparse(arg1):\n            # Convert scipy.sparse to cupyx.scipy.sparse\n            x = arg1.asformat(self.format)\n            data = cupy.array(x.data)\n            indices = cupy.array(x.indices, dtype='i')\n            indptr = cupy.array(x.indptr, dtype='i')\n            copy = False\n\n            if shape is None:\n                shape = arg1.shape\n            has_canonical_format = x.has_canonical_format\n\n        elif isinstance(arg1, tuple) and len(arg1) == 3:\n            data, indices, indptr = arg1\n            if not (base.isdense(data) and data.ndim == 1 and\n                    base.isdense(indices) and indices.ndim == 1 and\n                    base.isdense(indptr) and indptr.ndim == 1):\n                raise ValueError(\n                    'data, indices, and indptr should be 1-D')\n\n            if len(data) != len(indices):\n                raise ValueError('indices and data should have the same size')\n\n            has_canonical_format = False\n\n        elif base.isdense(arg1):\n            if arg1.ndim > 2:\n                raise TypeError('expected dimension <= 2 array or matrix')\n            elif arg1.ndim == 1:\n                arg1 = arg1[None]\n            elif arg1.ndim == 0:\n                arg1 = arg1[None, None]\n            data, indices, indptr = self._convert_dense(arg1)\n            copy = False\n            if shape is None:\n                shape = arg1.shape\n\n            has_canonical_format = True\n\n        else:\n            raise ValueError(\n                'Unsupported initializer format')\n\n        if dtype is None:\n            dtype = data.dtype\n        else:\n            dtype = numpy.dtype(dtype)\n\n        if dtype != 'f' and dtype != 'd' and dtype != 'F' and dtype != 'D':\n            raise ValueError(\n                'Only float32, float64, complex64 and complex128 '\n                'are supported')\n\n        data = data.astype(dtype, copy=copy)\n        sparse_data._data_matrix.__init__(self, data)\n\n        self.indices = indices.astype('i', copy=copy)\n        self.indptr = indptr.astype('i', copy=copy)\n\n        if shape is None:\n            shape = self._swap(len(indptr) - 1, int(indices.max()) + 1)\n\n        major, minor = self._swap(*shape)\n        if len(indptr) != major + 1:\n            raise ValueError('index pointer size (%d) should be (%d)'\n                             % (len(indptr), major + 1))\n\n        self._descr = cusparse.MatDescriptor.create()\n        self._shape = shape\n        self._has_canonical_format = has_canonical_format\n\n    def _with_data(self, data):\n        return self.__class__(\n            (data, self.indices.copy(), self.indptr.copy()), shape=self.shape)\n\n    def _convert_dense(self, x):\n        raise NotImplementedError\n\n    def _swap(self, x, y):\n        raise NotImplementedError\n\n    def _add_sparse(self, other, alpha, beta):\n        raise NotImplementedError\n\n    def _add(self, other, lhs_negative, rhs_negative):\n        if cupy.isscalar(other):\n            if other == 0:\n                if lhs_negative:\n                    return -self\n                else:\n                    return self.copy()\n            else:\n                raise NotImplementedError(\n                    'adding a nonzero scalar to a sparse matrix is not '\n                    'supported')\n        elif base.isspmatrix(other):\n            alpha = -1 if lhs_negative else 1\n            beta = -1 if rhs_negative else 1\n            return self._add_sparse(other, alpha, beta)\n        elif base.isdense(other):\n            if lhs_negative:\n                if rhs_negative:\n                    return -self.todense() - other\n                else:\n                    return other - self.todense()\n            else:\n                if rhs_negative:\n                    return self.todense() - other\n                else:\n                    return self.todense() + other\n        else:\n            return NotImplemented\n\n    def __add__(self, other):\n        return self._add(other, False, False)\n\n    def __radd__(self, other):\n        return self._add(other, False, False)\n\n    def __sub__(self, other):\n        return self._add(other, False, True)\n\n    def __rsub__(self, other):\n        return self._add(other, True, False)\n\n    def __getitem__(self, slices):\n        if isinstance(slices, tuple):\n            slices = list(slices)\n        elif isinstance(slices, list):\n            slices = list(slices)\n            if all([isinstance(s, int) for s in slices]):\n                slices = [slices]\n        else:\n            slices = [slices]\n\n        ellipsis = -1\n        n_ellipsis = 0\n        for i, s in enumerate(slices):\n            if s is None:\n                raise IndexError('newaxis is not supported')\n            elif s is Ellipsis:\n                ellipsis = i\n                n_ellipsis += 1\n        if n_ellipsis > 0:\n            ellipsis_size = self.ndim - (len(slices) - 1)\n            slices[ellipsis:ellipsis + 1] = [slice(None)] * ellipsis_size\n\n        if len(slices) == 2:\n            row, col = slices\n        elif len(slices) == 1:\n            row, col = slices[0], slice(None)\n        else:\n            raise IndexError('invalid number of indices')\n\n        major, minor = self._swap(row, col)\n        major_size, minor_size = self._swap(*self._shape)\n        if numpy.isscalar(major):\n            i = int(major)\n            if i < 0:\n                i += major_size\n            if not (0 <= i < major_size):\n                raise IndexError('index out of bounds')\n            if numpy.isscalar(minor):\n                j = int(minor)\n                if j < 0:\n                    j += minor_size\n                if not (0 <= j < minor_size):\n                    raise IndexError('index out of bounds')\n                return self._get_single(i, j)\n            elif minor == slice(None):\n                return self._get_major_slice(slice(i, i + 1))\n        elif isinstance(major, slice):\n            if minor == slice(None):\n                return self._get_major_slice(major)\n\n        raise ValueError('unsupported indexing')\n\n    def _get_single(self, major, minor):\n        start = self.indptr[major]\n        end = self.indptr[major + 1]\n        answer = cupy.zeros((), self.dtype)\n        data = self.data[start:end]\n        indices = self.indices[start:end]\n        if self.dtype.kind == 'c':\n            self._compress_getitem_complex_kern(\n                data.real, data.imag, indices, minor, answer.real, answer.imag)\n        else:\n            self._compress_getitem_kern(\n                data, indices, minor, answer)\n        return answer[()]\n\n    def _get_major_slice(self, major):\n        major_size, minor_size = self._swap(*self._shape)\n        # major.indices cannot be used because scipy.sparse behaves differently\n        major_start = major.start\n        major_stop = major.stop\n        major_step = major.step\n        if major_start is None:\n            major_start = 0\n        if major_stop is None:\n            major_stop = major_size\n        if major_step is None:\n            major_step = 1\n        if major_start < 0:\n            major_start += major_size\n        if major_stop < 0:\n            major_stop += major_size\n        major_start = max(min(major_start, major_size), 0)\n        major_stop = max(min(major_stop, major_size), 0)\n\n        if major_step != 1:\n            raise ValueError('slicing with step != 1 not supported')\n\n        if not (major_start <= major_stop):\n            raise IndexError('index out of bounds')\n\n        start = self.indptr[major_start]\n        stop = self.indptr[major_stop]\n        data = self.data[start:stop]\n        indptr = self.indptr[major_start:major_stop + 1] - start\n        indices = self.indices[start:stop]\n\n        shape = self._swap(len(indptr) - 1, minor_size)\n        return self.__class__(\n            (data, indices, indptr), shape=shape, dtype=self.dtype, copy=False)\n\n    @property\n    def has_canonical_format(self):\n        return self._has_canonical_format\n\n    def get_shape(self):\n        \"\"\"Returns the shape of the matrix.\n\n        Returns:\n            tuple: Shape of the matrix.\n        \"\"\"\n        return self._shape\n\n    def getnnz(self, axis=None):\n        \"\"\"Returns the number of stored values, including explicit zeros.\n\n        Args:\n            axis: Not supported yet.\n\n        Returns:\n            int: The number of stored values.\n\n        \"\"\"\n        if axis is None:\n            return self.data.size\n        else:\n            raise ValueError\n\n    # TODO(unno): Implement sorted_indices\n\n    def sum_duplicates(self):\n        if self._has_canonical_format:\n            return\n        if self.data.size == 0:\n            self._has_canonical_format = True\n            return\n        coo = self.tocoo()\n        coo.sum_duplicates()\n        self.__init__(coo.asformat(self.format))\n        self._has_canonical_format = True\n", "path": "cupyx/scipy/sparse/compressed.py"}]}