Exemplo n.º 1
0
def gauss_seidel_indexed(A, x, b,  indices, iterations=1, sweep='forward'):
    """Perform indexed Gauss-Seidel iteration on the linear system Ax=b

    In indexed Gauss-Seidel, the sequence in which unknowns are relaxed is
    specified explicitly.  In contrast, the standard Gauss-Seidel method
    always performs complete sweeps of all variables in increasing or 
    decreasing order.  The indexed method may be used to implement 
    specialized smoothers, like F-smoothing in Classical AMG.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    indices : ndarray
        Row indices to relax.
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.relaxation import gauss_seidel_indexed
    >>> import numpy
    >>> A = poisson((4,), format='csr')
    >>> x = numpy.array([0.0, 0.0, 0.0, 0.0])
    >>> b = numpy.array([0.0, 1.0, 2.0, 3.0])
    >>> gauss_seidel_indexed(A, x, b, [0,1,2,3])                #relax all four rows, in order
    >>> gauss_seidel_indexed(A, x, b, [0,1])                    #relax first two rows
    >>> gauss_seidel_indexed(A, x, b, [2,0])                    #relax row 2, then row 0
    >>> gauss_seidel_indexed(A, x, b, [2,3], sweep='backward')  #relax row 3, then row 2
    >>> gauss_seidel_indexed(A, x, b, [2,0,2])                  #relax row 2, then 0, then 2 again

    """
    A,x,b = make_system(A, x, b, formats=['csr'])

    indices = numpy.asarray(indices, dtype='intc')

    #if indices.min() < 0:
    #    raise ValueError('row index (%d) is invalid' % indices.min())
    #if indices.max() >= A.shape[0]
    #    raise ValueError('row index (%d) is invalid' % indices.max())

    if sweep == 'forward':
        row_start,row_stop,row_step = 0,len(indices),1
    elif sweep == 'backward':
        row_start,row_stop,row_step = len(indices)-1,-1,-1 
    elif sweep == 'symmetric':
        for iter in xrange(iterations):
            gauss_seidel_indexed(A, x, b, indices, iterations=1, sweep='forward')
            gauss_seidel_indexed(A, x, b, indices, iterations=1, sweep='backward')
        return
    else:
        raise ValueError('valid sweep directions are \'forward\', \'backward\', and \'symmetric\'')

    for iter in xrange(iterations):
        amg_core.gauss_seidel_indexed(A.indptr, A.indices, A.data,
                                            x, b, indices,
                                            row_start, row_stop, row_step)
Exemplo n.º 2
0
def gauss_seidel_indexed(A, x, b, indices, iterations=1, sweep='forward'):
    """Perform indexed Gauss-Seidel iteration on the linear system Ax=b

    In indexed Gauss-Seidel, the sequence in which unknowns are relaxed is
    specified explicitly.  In contrast, the standard Gauss-Seidel method
    always performs complete sweeps of all variables in increasing or 
    decreasing order.  The indexed method may be used to implement 
    specialized smoothers, like F-smoothing in Classical AMG.

    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    indices : ndarray
        Row indices to relax.
    iterations : int
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

    Returns
    -------
    Nothing, x will be modified in place.

    Examples
    --------
    >>> from pyamg.gallery import poisson
    >>> from pyamg.relaxation import gauss_seidel_indexed
    >>> import numpy
    >>> A = poisson((4,), format='csr')
    >>> x = numpy.array([0.0, 0.0, 0.0, 0.0])
    >>> b = numpy.array([0.0, 1.0, 2.0, 3.0])
    >>> gauss_seidel_indexed(A, x, b, [0,1,2,3])                #relax all four rows, in order
    >>> gauss_seidel_indexed(A, x, b, [0,1])                    #relax first two rows
    >>> gauss_seidel_indexed(A, x, b, [2,0])                    #relax row 2, then row 0
    >>> gauss_seidel_indexed(A, x, b, [2,3], sweep='backward')  #relax row 3, then row 2
    >>> gauss_seidel_indexed(A, x, b, [2,0,2])                  #relax row 2, then 0, then 2 again

    """
    A, x, b = make_system(A, x, b, formats=['csr'])

    indices = numpy.asarray(indices, dtype='intc')

    #if indices.min() < 0:
    #    raise ValueError('row index (%d) is invalid' % indices.min())
    #if indices.max() >= A.shape[0]
    #    raise ValueError('row index (%d) is invalid' % indices.max())

    if sweep == 'forward':
        row_start, row_stop, row_step = 0, len(indices), 1
    elif sweep == 'backward':
        row_start, row_stop, row_step = len(indices) - 1, -1, -1
    elif sweep == 'symmetric':
        for iter in xrange(iterations):
            gauss_seidel_indexed(A,
                                 x,
                                 b,
                                 indices,
                                 iterations=1,
                                 sweep='forward')
            gauss_seidel_indexed(A,
                                 x,
                                 b,
                                 indices,
                                 iterations=1,
                                 sweep='backward')
        return
    else:
        raise ValueError(
            'valid sweep directions are \'forward\', \'backward\', and \'symmetric\''
        )

    for iter in xrange(iterations):
        amg_core.gauss_seidel_indexed(A.indptr, A.indices, A.data, x, b,
                                      indices, row_start, row_stop, row_step)