예제 #1
0
파일: _solve.py 프로젝트: viantirreau/cupy
def spilu(A, drop_tol=None, fill_factor=None, drop_rule=None,
          permc_spec=None, diag_pivot_thresh=None, relax=None,
          panel_size=None, options={}):
    """Computes the incomplete LU decomposition of a sparse square matrix.

    Args:
        A (cupyx.scipy.sparse.spmatrix): Sparse matrix to factorize.
        drop_tol (float): (For further augments, see
            :func:`scipy.sparse.linalg.spilu`)
        fill_factor (float):
        drop_rule (str):
        permc_spec (str):
        diag_pivot_thresh (float):
        relax (int):
        panel_size (int):
        options (dict):

    Returns:
        cupyx.scipy.sparse.linalg.SuperLU:
            Object which has a ``solve`` method.

    Note:
        This function computes incomplete LU decomposition of a sparse matrix
        on the CPU using `scipy.sparse.linalg.spilu` (unless you set
        ``fill_factor`` to ``1``). Therefore, incomplete LU decomposition is
        not accelerated on the GPU. On the other hand, the computation of
        solving linear equations using the ``solve`` method, which this
        function returns, is performed on the GPU.

        If you set ``fill_factor`` to ``1``, this function computes incomplete
        LU decomposition on the GPU, but without fill-in or pivoting.

    .. seealso:: :func:`scipy.sparse.linalg.spilu`
    """
    if not scipy_available:
        raise RuntimeError('scipy is not available')
    if not sparse.isspmatrix(A):
        raise TypeError('A must be cupyx.scipy.sparse.spmatrix')
    if A.shape[0] != A.shape[1]:
        raise ValueError('A must be a square matrix (A.shape: {})'
                         .format(A.shape))
    if A.dtype.char not in 'fdFD':
        raise TypeError('Invalid dtype (actual: {})'.format(A.dtype))

    if fill_factor == 1:
        # Computes ILU(0) on the GPU using cuSparse functions
        if not sparse.isspmatrix_csr(A):
            a = A.tocsr()
        else:
            a = A.copy()
        cusparse.csrilu02(a)
        return CusparseLU(a)

    a = A.get().tocsc()
    a_inv = scipy.sparse.linalg.spilu(
        a, fill_factor=fill_factor, drop_tol=drop_tol, drop_rule=drop_rule,
        permc_spec=permc_spec, diag_pivot_thresh=diag_pivot_thresh,
        relax=relax, panel_size=panel_size, options=options)
    return SuperLU(a_inv)
예제 #2
0
 def test_csrilu02(self, dtype):
     dtype = numpy.dtype(dtype)
     a_ref = self._make_matrix(dtype)
     a = sparse.csr_matrix(a_ref)
     cusparse.csrilu02(a, level_info=self.level_info)
     a = a.todense()
     al = cupy.tril(a, k=-1)
     al = al + cupy.diag(cupy.ones((self.n, ), dtype=dtype.char.lower()))
     au = cupy.triu(a)
     a = al @ au
     tol = self._tol[dtype.char.lower()]
     cupy.testing.assert_allclose(a, a_ref, atol=tol, rtol=tol)
예제 #3
0
    def test_invalid_cases(self):
        dtype = numpy.dtype('d')
        a_ref = self._make_matrix(dtype)

        # invalid format
        a = sparse.csc_matrix(a_ref)
        with pytest.raises(TypeError):
            cusparse.csrilu02(a, level_info=self.level_info)

        # invalid shape
        a = cupy.ones((self.n, self.n + 1), dtype=dtype)
        a = sparse.csr_matrix(a)
        with pytest.raises(ValueError):
            cusparse.csrilu02(a, level_info=self.level_info)

        # matrix with zero diagonal element
        a = a_ref
        a[-1, -1] = 0
        a = sparse.csr_matrix(a)
        with pytest.raises(ValueError):
            cusparse.csrilu02(a, level_info=self.level_info)

        # singular matrix
        a = a_ref
        a[1:] = a[0]
        a = sparse.csr_matrix(a)
        with pytest.raises(ValueError):
            cusparse.csrilu02(a, level_info=self.level_info)