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)
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)