Exemplo n.º 1
0
def gauss_seidel_nr(A, x, b, iterations=1, sweep='forward', omega=1.0, Dinv=None):
    """Perform Gauss-Seidel iterations on the linear system A.H A x = A.H b
    
    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : { ndarray }
        Approximate solution (length N)
    b : { ndarray }
        Right-hand side (length N)
    iterations : { int }
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep
    omega : { float}
        Relaxation parameter typically in (0, 2)
        if omega != 1.0, then algorithm becomes SOR on A.H A
    Dinv : { ndarray}
        Inverse of diag(A.H A),  (length N)

    Returns
    -------
    Nothing, x will be modified in place.
    
    References
    ----------
    .. [1] Yousef Saad, "Iterative Methods for Sparse Linear Systems, 
       Second Edition", SIAM, pp. 247-9, 2003
       http://www-users.cs.umn.edu/~saad/books.html
 
    
    Examples
    --------
    >>> ## Use NR Gauss-Seidel as a Stand-Alone Solver
    >>> from pyamg.relaxation import *
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy
    >>> A = poisson((10,10), format='csr')
    >>> x0 = numpy.zeros((A.shape[0],1))
    >>> b = numpy.ones((A.shape[0],1))
    >>> gauss_seidel_nr(A, x0, b, iterations=10, sweep='symmetric')
    >>> print norm(b-A*x0)
    8.45044864352
    >>> #
    >>> ## Use NR Gauss-Seidel as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=numpy.ones((A.shape[0],1)),
    ...      coarse_solver='pinv2', max_coarse=50,
    ...      presmoother=('gauss_seidel_nr', {'sweep' : 'symmetric'}), 
    ...      postsmoother=('gauss_seidel_nr', {'sweep' : 'symmetric'}))
    >>> x0=numpy.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)
    """
    
    A,x,b = make_system(A, x, b, formats=['csc'])
    
    # Dinv for A.H*A
    if Dinv == None:
        Dinv = numpy.ravel(get_diagonal(A, norm_eq=1, inv=True))
    
    if sweep == 'forward':
        col_start,col_stop,col_step = 0,len(x),1
    elif sweep == 'backward':
        col_start,col_stop,col_step = len(x)-1,-1,-1 
    elif sweep == 'symmetric':
        for iter in xrange(iterations):
            gauss_seidel_nr(A, x, b, iterations=1, sweep='forward', omega=omega, Dinv=Dinv)
            gauss_seidel_nr(A, x, b, iterations=1, sweep='backward', omega=omega, Dinv=Dinv)
        return
    else:
        raise ValueError("valid sweep directions are 'forward', 'backward', and 'symmetric'")

    ##
    # Calculate initial residual
    r = b - A*x

    for i in xrange(iterations):
        amg_core.gauss_seidel_nr(A.indptr, A.indices, A.data,
                                           x, r, col_start,
                                           col_stop, col_step, Dinv, omega)
Exemplo n.º 2
0
def gauss_seidel_nr(A,
                    x,
                    b,
                    iterations=1,
                    sweep='forward',
                    omega=1.0,
                    Dinv=None):
    """Perform Gauss-Seidel iterations on the linear system A.H A x = A.H b
    
    Parameters
    ----------
    A : csr_matrix
        Sparse NxN matrix
    x : { ndarray }
        Approximate solution (length N)
    b : { ndarray }
        Right-hand side (length N)
    iterations : { int }
        Number of iterations to perform
    sweep : {'forward','backward','symmetric'}
        Direction of sweep
    omega : { float}
        Relaxation parameter typically in (0, 2)
        if omega != 1.0, then algorithm becomes SOR on A.H A
    Dinv : { ndarray}
        Inverse of diag(A.H A),  (length N)

    Returns
    -------
    Nothing, x will be modified in place.
    
    References
    ----------
    .. [1] Yousef Saad, "Iterative Methods for Sparse Linear Systems, 
       Second Edition", SIAM, pp. 247-9, 2003
       http://www-users.cs.umn.edu/~saad/books.html
 
    
    Examples
    --------
    >>> ## Use NR Gauss-Seidel as a Stand-Alone Solver
    >>> from pyamg.relaxation import *
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy
    >>> A = poisson((10,10), format='csr')
    >>> x0 = numpy.zeros((A.shape[0],1))
    >>> b = numpy.ones((A.shape[0],1))
    >>> gauss_seidel_nr(A, x0, b, iterations=10, sweep='symmetric')
    >>> print norm(b-A*x0)
    8.45044864352
    >>> #
    >>> ## Use NR Gauss-Seidel as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=numpy.ones((A.shape[0],1)),
    ...      coarse_solver='pinv2', max_coarse=50,
    ...      presmoother=('gauss_seidel_nr', {'sweep' : 'symmetric'}), 
    ...      postsmoother=('gauss_seidel_nr', {'sweep' : 'symmetric'}))
    >>> x0=numpy.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)
    """

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

    # Dinv for A.H*A
    if Dinv == None:
        Dinv = numpy.ravel(get_diagonal(A, norm_eq=1, inv=True))

    if sweep == 'forward':
        col_start, col_stop, col_step = 0, len(x), 1
    elif sweep == 'backward':
        col_start, col_stop, col_step = len(x) - 1, -1, -1
    elif sweep == 'symmetric':
        for iter in xrange(iterations):
            gauss_seidel_nr(A,
                            x,
                            b,
                            iterations=1,
                            sweep='forward',
                            omega=omega,
                            Dinv=Dinv)
            gauss_seidel_nr(A,
                            x,
                            b,
                            iterations=1,
                            sweep='backward',
                            omega=omega,
                            Dinv=Dinv)
        return
    else:
        raise ValueError(
            "valid sweep directions are 'forward', 'backward', and 'symmetric'"
        )

    ##
    # Calculate initial residual
    r = b - A * x

    for i in xrange(iterations):
        amg_core.gauss_seidel_nr(A.indptr, A.indices, A.data, x, r, col_start,
                                 col_stop, col_step, Dinv, omega)