def lsqr(A, b): """Solves linear system with QR decomposition. Find the solution to a large, sparse, linear system of equations. The function solves ``Ax = b``. Given two-dimensional matrix ``A`` is decomposed into ``Q * R``. Args: A (cupy.ndarray or cupyx.scipy.sparse.csr_matrix): The input matrix with dimension ``(N, N)`` b (cupy.ndarray): Right-hand side vector. Returns: tuple: Its length must be ten. It has same type elements as SciPy. Only the first element, the solution vector ``x``, is available and other elements are expressed as ``None`` because the implementation of cuSOLVER is different from the one of SciPy. You can easily calculate the fourth element by ``norm(b - Ax)`` and the ninth element by ``norm(x)``. .. seealso:: :func:`scipy.sparse.linalg.lsqr` """ if runtime.is_hip: raise RuntimeError('HIP does not support lsqr') if not sparse.isspmatrix_csr(A): A = sparse.csr_matrix(A) # csr_matrix is 2d _util._assert_stacked_square(A) _util._assert_cupy_array(b) m = A.shape[0] if b.ndim != 1 or len(b) != m: raise ValueError('b must be 1-d array whose size is same as A') # Cast to float32 or float64 if A.dtype == 'f' or A.dtype == 'd': dtype = A.dtype else: dtype = numpy.promote_types(A.dtype, 'f') handle = device.get_cusolver_sp_handle() nnz = A.nnz tol = 1.0 reorder = 1 x = cupy.empty(m, dtype=dtype) singularity = numpy.empty(1, numpy.int32) if dtype == 'f': csrlsvqr = cusolver.scsrlsvqr else: csrlsvqr = cusolver.dcsrlsvqr csrlsvqr( handle, m, nnz, A._descr.descriptor, A.data.data.ptr, A.indptr.data.ptr, A.indices.data.ptr, b.data.ptr, tol, reorder, x.data.ptr, singularity.ctypes.data) # The return type of SciPy is always float64. Therefore, x must be casted. x = x.astype(numpy.float64) ret = (x, None, None, None, None, None, None, None, None, None) return ret
def csrlsvqr(A, b, tol=0, reorder=1): """Solves the linear system ``Ax = b`` using QR factorization. Args: A (cupyx.scipy.sparse.csr_matrix): Sparse matrix with dimension ``(M, M)``. b (cupy.ndarray): Dense vector with dimension ``(M,)``. tol (float): Tolerance to decide if singular or not. reorder (int): Reordering scheme to reduce zero fill-in. 1: symrcm is used. 2: symamd is used. 3: csrmetisnd is used. else: no reordering. """ if not check_availability('csrlsvqr'): raise RuntimeError('csrlsvqr is not available.') if not _cupyx.scipy.sparse.isspmatrix_csr(A): raise ValueError('A must be CSR sparse matrix') if not isinstance(b, _cupy.ndarray): raise ValueError('b must be cupy.ndarray') if b.ndim != 1: raise ValueError('b.ndim must be 1 (actual: {})'.format(b.ndim)) if not (A.shape[0] == A.shape[1] == b.shape[0]): raise ValueError('invalid shape') if A.dtype != b.dtype: raise TypeError('dtype mismatch') dtype = A.dtype if dtype.char == 'f': t = 's' elif dtype.char == 'd': t = 'd' elif dtype.char == 'F': t = 'c' elif dtype.char == 'D': t = 'z' else: raise TypeError('Invalid dtype (actual: {})'.format(dtype)) solve = getattr(_cusolver, t + 'csrlsvqr') tol = max(tol, 0) m = A.shape[0] x = _cupy.empty((m,), dtype=dtype) singularity = _numpy.empty((1,), _numpy.int32) handle = _device.get_cusolver_sp_handle() solve(handle, m, A.nnz, A._descr.descriptor, A.data.data.ptr, A.indptr.data.ptr, A.indices.data.ptr, b.data.ptr, tol, reorder, x.data.ptr, singularity.ctypes.data) if singularity[0] >= 0: _warnings.warn('A is not positive definite or near singular under ' 'tolerance {} (singularity: {})'. format(tol, singularity)) return x
def lschol(A, b): """Solves linear system with cholesky decomposition. Find the solution to a large, sparse, linear system of equations. The function solves ``Ax = b``. Given two-dimensional matrix ``A`` is decomposed into ``L * L^*``. Args: A (cupy.ndarray or cupy.sparse.csr_matrix): The input matrix with dimension ``(N, N)``. Must be positive-definite input matrix. Only symmetric real matrix is supported currently. b (cupy.ndarray): Right-hand side vector. Returns: ret (cupy.ndarray): The solution vector ``x``. """ if not cuda.cusolver_enabled: raise RuntimeError('Current cupy only supports cusolver in CUDA 8.0') if not cupy.sparse.isspmatrix_csr(A): A = cupy.sparse.csr_matrix(A) util._assert_nd_squareness(A) util._assert_cupy_array(b) m = A.shape[0] if b.ndim != 1 or len(b) != m: raise ValueError('b must be 1-d array whose size is same as A') # Cast to float32 or float64 if A.dtype == 'f' or A.dtype == 'd': dtype = A.dtype else: dtype = numpy.find_common_type((A.dtype, 'f'), ()) handle = device.get_cusolver_sp_handle() nnz = A.nnz tol = 1.0 reorder = 1 x = cupy.empty(m, dtype=dtype) singularity = numpy.empty(1, numpy.int32) if dtype == 'f': csrlsvchol = cusolver.scsrlsvchol else: csrlsvchol = cusolver.dcsrlsvchol csrlsvchol(handle, m, nnz, A._descr.descriptor, A.data.data.ptr, A.indptr.data.ptr, A.indices.data.ptr, b.data.ptr, tol, reorder, x.data.ptr, singularity.ctypes.data) # The return type of SciPy is always float64. x = x.astype(numpy.float64) return x