(A, x, b, iterations=1, subdomain=None, subdomain_ptr=None,
            inv_subblock=None, inv_subblock_ptr=None, sweep='forward')
Perform Overlapping multiplicative Schwarz on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    subdomain : int array
        Linear array containing each subdomain's elements
    subdomain_ptr : int array
        Pointer in subdomain, such that
        subdomain[subdomain_ptr[i]:subdomain_ptr[i+1]]]
        contains the _sorted_ indices in subdomain i
    inv_subblock : int_array
        Linear array containing each subdomain's
        inverted diagonal block of A
    inv_subblock_ptr : int array
        Pointer in inv_subblock, such that
        inv_subblock[inv_subblock_ptr[i]:inv_subblock_ptr[i+1]]]
        contains the inverted diagonal block of A for the
        i-th subdomain in _row_ major order
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

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

    Notes
    -----
    If subdomains is None, then a point-wise iteration takes place,
    with the overlapping region defined by each degree-of-freedom's
    neighbors in the matrix graph.

    If subdomains is not None, but subblocks is, then the subblocks
    are formed internally.

    Currently only supports CSR matrices

    Examples
    --------
    >>> # Use Overlapping Schwarz as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import schwarz
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> schwarz(A, x0, b, iterations=10)
    >>> print(f'{norm(b-A*x0):2.4}')
    0.1263
    >>> #
    >>> # Schwarz as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother='schwarz',
    ...         postsmoother='schwarz')
    >>> x0=np.zeros((A.shape[0],1))
    >>> residuals=[]
    >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)
Perform Overlapping multiplicative Schwarz on the linear system Ax=b.
Perform Overlapping multiplicative Schwarz on the linear system Ax = b .
def schwarz(A, x, b, iterations=1, subdomain=None, subdomain_ptr=None,
            inv_subblock=None, inv_subblock_ptr=None, sweep='forward'):
    """Perform Overlapping multiplicative Schwarz on the linear system Ax=b.

    Parameters
    ----------
    A : csr_matrix, bsr_matrix
        Sparse NxN matrix
    x : ndarray
        Approximate solution (length N)
    b : ndarray
        Right-hand side (length N)
    iterations : int
        Number of iterations to perform
    subdomain : int array
        Linear array containing each subdomain's elements
    subdomain_ptr : int array
        Pointer in subdomain, such that
        subdomain[subdomain_ptr[i]:subdomain_ptr[i+1]]]
        contains the _sorted_ indices in subdomain i
    inv_subblock : int_array
        Linear array containing each subdomain's
        inverted diagonal block of A
    inv_subblock_ptr : int array
        Pointer in inv_subblock, such that
        inv_subblock[inv_subblock_ptr[i]:inv_subblock_ptr[i+1]]]
        contains the inverted diagonal block of A for the
        i-th subdomain in _row_ major order
    sweep : {'forward','backward','symmetric'}
        Direction of sweep

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

    Notes
    -----
    If subdomains is None, then a point-wise iteration takes place,
    with the overlapping region defined by each degree-of-freedom's
    neighbors in the matrix graph.

    If subdomains is not None, but subblocks is, then the subblocks
    are formed internally.

    Currently only supports CSR matrices

    Examples
    --------
    >>> # Use Overlapping Schwarz as a Stand-Alone Solver
    >>> from pyamg.relaxation.relaxation import schwarz
    >>> from pyamg.gallery import poisson
    >>> from pyamg.util.linalg import norm
    >>> import numpy as np
    >>> A = poisson((10,10), format='csr')
    >>> x0 = np.zeros((A.shape[0],1))
    >>> b = np.ones((A.shape[0],1))
    >>> schwarz(A, x0, b, iterations=10)
    >>> print(f'{norm(b-A*x0):2.4}')
    0.1263
    >>> #
    >>> # Schwarz as the Multigrid Smoother
    >>> from pyamg import smoothed_aggregation_solver
    >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
    ...         coarse_solver='pinv', max_coarse=50,
    ...         presmoother='schwarz',
    ...         postsmoother='schwarz')
    >>> x0=np.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=['csr'])
    A.sort_indices()

    if subdomain is None and inv_subblock is not None:
        raise ValueError('inv_subblock must be None if subdomain is None')

    # If no subdomains are defined, default is to use the sparsity pattern of A
    # to define the overlapping regions
    (subdomain, subdomain_ptr, inv_subblock, inv_subblock_ptr) = \
        schwarz_parameters(A, subdomain, subdomain_ptr,
                           inv_subblock, inv_subblock_ptr)

    if sweep not in ('forward', 'backward', 'symmetric'):
        raise ValueError("valid sweep directions: 'forward', 'backward', and 'symmetric'")

    if sweep == 'forward':
        row_start, row_stop, row_step = 0, subdomain_ptr.shape[0]-1, 1
    elif sweep == 'backward':
        row_start, row_stop, row_step = subdomain_ptr.shape[0]-2, -1, -1
    elif sweep == 'symmetric':
        for _iter in range(iterations):
            schwarz(A, x, b, iterations=1, subdomain=subdomain,
                    subdomain_ptr=subdomain_ptr, inv_subblock=inv_subblock,
                    inv_subblock_ptr=inv_subblock_ptr, sweep='forward')
            schwarz(A, x, b, iterations=1, subdomain=subdomain,
                    subdomain_ptr=subdomain_ptr, inv_subblock=inv_subblock,
                    inv_subblock_ptr=inv_subblock_ptr, sweep='backward')
        return

    # Call C code, need to make sure that subdomains are sorted and unique
    for _iter in range(iterations):
        amg_core.overlapping_schwarz_csr(A.indptr, A.indices, A.data,
                                         x, b, inv_subblock, inv_subblock_ptr,
                                         subdomain, subdomain_ptr,
                                         subdomain_ptr.shape[0]-1, A.shape[0],
                                         row_start, row_stop, row_step)
def schwarz ( A , x , b , iterations = 1 , subdomain = None , subdomain_ptr = None , inv_subblock = None , inv_subblock_ptr = None , sweep = 'forward' ) : A , x , b = make_system ( A , x , b , formats = [ 'csr' ] ) A . sort_indices ( ) if subdomain is None and inv_subblock is not None : raise ValueError ( 'inv_subblock must be None if subdomain is None' ) # If no subdomains are defined, default is to use the sparsity pattern of A # to define the overlapping regions ( subdomain , subdomain_ptr , inv_subblock , inv_subblock_ptr ) = schwarz_parameters ( A , subdomain , subdomain_ptr , inv_subblock , inv_subblock_ptr ) if sweep not in ( 'forward' , 'backward' , 'symmetric' ) : raise ValueError ( "valid sweep directions: 'forward', 'backward', and 'symmetric'" ) if sweep == 'forward' : row_start , row_stop , row_step = 0 , subdomain_ptr . shape [ 0 ] - 1 , 1 elif sweep == 'backward' : row_start , row_stop , row_step = subdomain_ptr . shape [ 0 ] - 2 , - 1 , - 1 elif sweep == 'symmetric' : for _iter in range ( iterations ) : schwarz ( A , x , b , iterations = 1 , subdomain = subdomain , subdomain_ptr = subdomain_ptr , inv_subblock = inv_subblock , inv_subblock_ptr = inv_subblock_ptr , sweep = 'forward' ) schwarz ( A , x , b , iterations = 1 , subdomain = subdomain , subdomain_ptr = subdomain_ptr , inv_subblock = inv_subblock , inv_subblock_ptr = inv_subblock_ptr , sweep = 'backward' ) return # Call C code, need to make sure that subdomains are sorted and unique for _iter in range ( iterations ) : amg_core . overlapping_schwarz_csr ( A . indptr , A . indices , A . data , x , b , inv_subblock , inv_subblock_ptr , subdomain , subdomain_ptr , subdomain_ptr . shape [ 0 ] - 1 , A . shape [ 0 ] , row_start , row_stop , row_step )