def _comparison(self, other, op, op_name): if _util.isscalarlike(other): data = cupy.asarray(other, dtype=self.dtype).reshape(1) if numpy.isnan(data[0]): if op_name == '_ne_': return csr_matrix(cupy.ones(self.shape, dtype=numpy.bool_)) else: return csr_matrix(self.shape, dtype=numpy.bool_) indices = cupy.zeros((1, ), dtype=numpy.int32) indptr = cupy.arange(2, dtype=numpy.int32) other = csr_matrix((data, indices, indptr), shape=(1, 1)) return binopt_csr(self, other, op_name) elif _util.isdense(other): return op(self.todense(), other) elif isspmatrix_csr(other): self.sum_duplicates() other.sum_duplicates() if op_name in ('_ne_', '_lt_', '_gt_'): return binopt_csr(self, other, op_name) warnings.warn( "Comparing sparse matrices using ==, <=, and >= is " "inefficient, try using !=, <, or > instead.", SparseEfficiencyWarning) if op_name == '_eq_': opposite_op_name = '_ne_' elif op_name == '_le_': opposite_op_name = '_gt_' elif op_name == '_ge_': opposite_op_name = '_lt_' res = binopt_csr(self, other, opposite_op_name) out = cupy.logical_not(res.toarray()) return csr_matrix(out) raise NotImplementedError
def _maximum_minimum(self, other, cupy_op, op_name, dense_check): if _util.isscalarlike(other): other = cupy.asarray(other, dtype=self.dtype) if dense_check(other): dtype = self.dtype # Note: This is a work-around to make the output dtype the same # as SciPy. It might be SciPy version dependent. if dtype == numpy.float32: dtype = numpy.float64 elif dtype == numpy.complex64: dtype = numpy.complex128 dtype = cupy.result_type(dtype, other) other = other.astype(dtype, copy=False) # Note: The computation steps below are different from SciPy. new_array = cupy_op(self.todense(), other) return csr_matrix(new_array) else: self.sum_duplicates() new_data = cupy_op(self.data, other) return csr_matrix((new_data, self.indices, self.indptr), shape=self.shape, dtype=self.dtype) elif _util.isdense(other): self.sum_duplicates() other = cupy.atleast_2d(other) return cupy_op(self.todense(), other) elif isspmatrix_csr(other): self.sum_duplicates() other.sum_duplicates() return binopt_csr(self, other, op_name) raise NotImplementedError
def __truediv__(self, other): """Point-wise division by another matrix, vector or scalar""" if _util.isscalarlike(other): dtype = self.dtype if dtype == numpy.float32: # Note: This is a work-around to make the output dtype the same # as SciPy. It might be SciPy version dependent. dtype = numpy.float64 dtype = cupy.result_type(dtype, other) d = cupy.reciprocal(other, dtype=dtype) return multiply_by_scalar(self, d) elif _util.isdense(other): other = cupy.atleast_2d(other) check_shape_for_pointwise_op(self.shape, other.shape) return self.todense() / other elif base.isspmatrix(other): # Note: If broadcasting is needed, an exception is raised here for # compatibility with SciPy, as SciPy does not support broadcasting # in the "sparse / sparse" case. check_shape_for_pointwise_op(self.shape, other.shape, allow_broadcasting=False) dtype = numpy.promote_types(self.dtype, other.dtype) if dtype.char not in 'FD': dtype = numpy.promote_types(numpy.float64, dtype) # Note: The following implementation converts two sparse matrices # into dense matrices and then performs a point-wise division, # which can use lots of memory. self_dense = self.todense().astype(dtype, copy=False) return self_dense / other.todense() raise NotImplementedError
def multiply(self, other): """Point-wise multiplication by another matrix, vector or scalar""" if cupy.isscalar(other): return multiply_by_scalar(self, other) elif _util.isdense(other): self.sum_duplicates() other = cupy.atleast_2d(other) return multiply_by_dense(self, other) elif isspmatrix_csr(other): self.sum_duplicates() other.sum_duplicates() return multiply_by_csr(self, other) else: msg = 'expected scalar, dense matrix/vector or csr matrix' raise TypeError(msg)