Repository: scipy/scipy
File: scipy/sparse/_compressed.py (Python)

Code before:

    def diagonal(self, k=0):
        M, N = self._swap(self.shape)
        k, _ = self._swap((k, -k))

        if k <= -M or k >= N:
            return np.empty(0, dtype=self.data.dtype)
        y = np.empty(min(M + min(k, 0), N - max(k, 0)), dtype=upcast(self.dtype))
        csr_diagonal(k, M, N, self.indptr, self.indices, self.data, y)
        return y

    diagonal.__doc__ = _spbase.diagonal.__doc__

    #####################
    # Reduce operations #
    #####################

    def sum(self, axis=None, dtype=None, out=None):
        """Sum the array/matrix over the given axis.  If the axis is None, sum
        over both rows and columns, returning a scalar.
        """
        # The _spbase base class already does axis=None and major axis efficiently
        # so we only do the case axis= minor axis
        if (self.ndim == 2 and not hasattr(self, 'blocksize') and
                axis in self._swap(((1, -1), (0, -2)))[0]):
            # faster than multiplication for large major axis in CSC/CSR
            
            if dtype is not None:
                self_to_reduce = self.astype(dtype, copy=False)
                res_dtype = dtype
            else:
                self_to_reduce = self
                res_dtype = get_sum_dtype(self.dtype)
            
            # Fast path: reduce along minor axis
            ret = np.zeros(len(self_to_reduce.indptr) - 1, dtype=res_dtype)
            major_index, value = self_to_reduce._minor_reduce(np.add)
            ret[major_index] = value
            ret = self_to_reduce._ascontainer(ret)
            if axis % 2 == 1:
                ret = ret.T

            if out is not None:
                out[...] = ret
                return out
            return ret
        else:
            return _spbase.sum(self, axis=axis, dtype=dtype, out=out)

    sum.__doc__ = _spbase.sum.__doc__


Review comment (suggestion):
```suggestion
            # faster than multiplication for large minor axis in CSC/CSR
```

Code after:

    def diagonal(self, k=0):
        M, N = self._swap(self.shape)
        k, _ = self._swap((k, -k))

        if k <= -M or k >= N:
            return np.empty(0, dtype=self.data.dtype)
        y = np.empty(min(M + min(k, 0), N - max(k, 0)), dtype=upcast(self.dtype))
        csr_diagonal(k, M, N, self.indptr, self.indices, self.data, y)
        return y

    diagonal.__doc__ = _spbase.diagonal.__doc__

    #####################
    # Reduce operations #
    #####################

    def sum(self, axis=None, dtype=None, out=None):
        """Sum the array/matrix over the given axis.  If the axis is None, sum
        over both rows and columns, returning a scalar.
        """
        # The _spbase base class already does axis=None and major axis efficiently
        # so we only do the case axis= minor axis
        if (self.ndim == 2 and not hasattr(self, 'blocksize') and
                axis in self._swap(((1, -1), (0, -2)))[0]):
            # faster than multiplication for large minor axis in CSC/CSR
            
            res_dtype = get_sum_dtype(self.dtype) if dtype is None else dtype
            self_to_reduce = self.astype(res_dtype, copy=False)
            
            # Fast path: reduce along minor axis
            ret = np.zeros(len(self_to_reduce.indptr) - 1, dtype=res_dtype)
            major_index, value = self_to_reduce._minor_reduce(np.add)
            ret[major_index] = value
            ret = self_to_reduce._ascontainer(ret)
            if axis % 2 == 1:
                ret = ret.T

            return ret.sum(axis=(), dtype=res_dtype, out=out)
        else:
            return _spbase.sum(self, axis=axis, dtype=dtype, out=out)

    sum.__doc__ = _spbase.sum.__doc__

    def _minor_reduce(self, ufunc, data=None):
        """Reduce nonzeros with a ufunc over the minor axis when non-empty

        Can be applied to a function of self.data by supplying data parameter.

        Warning: this does not call sum_duplicates()