def FC_jacobi(A, x, b, Cpts, Fpts, iterations=1, F_iterations=1, C_iterations=1, omega=1.0): """Perform FC Jacobi iteration on the linear system Ax=b, that is x_f = (1-omega)x_f + omega*Dff^{-1}(b_f - Aff*xf - Afc*xc) x_c = (1-omega)x_c + omega*Dff^{-1}(b_c - Acf*xf - Acc*xc) where xf is x restricted to F-points, and likewise for c subscripts. Parameters ---------- A : csr_matrix Sparse NxN matrix x : ndarray Approximate solution (length N) b : ndarray Right-hand side (length N) Cpts : array ints List of C-points Fpts : array ints List of F-points iterations : int Number of iterations to perform of total FC-cycle F_iterations : int Number of sweeps of F-relaxation to perform C_iterations : int Number of sweeps of C-relaxation to perform omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. """ A, x, b = make_system(A, x, b, formats=['csr', 'bsr']) # Create uniform type, convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) if sparse.isspmatrix_csr(A): for iter in range(iterations): for Fiter in range(F_iterations): amg_core.jacobi_indexed(A.indptr, A.indices, A.data, x, b, Fpts, omega) for Citer in range(C_iterations): amg_core.jacobi_indexed(A.indptr, A.indices, A.data, x, b, Cpts, omega) else: R, C = A.blocksize if R != C: raise ValueError('BSR blocks must be square') for iter in range(iterations): for Fiter in range(F_iterations): amg_core.bsr_jacobi_indexed(A.indptr, A.indices, np.ravel(A.data), x, b, Fpts, R, omega) for Citer in range(C_iterations): amg_core.bsr_jacobi_indexed(A.indptr, A.indices, np.ravel(A.data), x, b, Cpts, R, omega)
def jacobi_ne(A, x, b, iterations=1, omega=1.0): """Perform Jacobi iterations on the linear system A A.H x = A.H b (Also known as Cimmino relaxation) 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 omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. References ---------- .. [1] Brandt, Ta'asan. "Multigrid Method For Nearly Singular And Slightly Indefinite Problems." 1985. NASA Technical Report Numbers: ICASE-85-57; NAS 1.26:178026; NASA-CR-178026; .. [2] Kaczmarz. Angenaeherte Aufloesung von Systemen Linearer Gleichungen. Bull. Acad. Polon. Sci. Lett. A 35, 355-57. 1937 .. [3] Cimmino. La ricerca scientifica ser. II 1. Pubbliz. dell'Inst. pre le Appl. del Calculo 34, 326-333, 1938. Examples -------- >>> ## Use NE Jacobi as a Stand-Alone Solver >>> from pyamg.relaxation import jacobi_ne >>> from pyamg.gallery import poisson >>> from pyamg.util.linalg import norm >>> import numpy >>> A = poisson((50,50), format='csr') >>> x0 = numpy.zeros((A.shape[0],1)) >>> b = numpy.ones((A.shape[0],1)) >>> jacobi_ne(A, x0, b, iterations=10, omega=2.0/3.0) >>> print norm(b-A*x0) 49.3886046066 >>> # >>> ## Use NE Jacobi 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=('jacobi_ne', {'iterations' : 2, 'omega' : 4.0/3.0}), ... postsmoother=('jacobi_ne', {'iterations' : 2, 'omega' : 4.0/3.0})) >>> 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=['csr']) sweep = slice(None) (row_start,row_stop,row_step) = sweep.indices(A.shape[0]) temp = numpy.zeros_like(x) # Dinv for A*A.H Dinv = get_diagonal(A, norm_eq=2, inv=True) # Create uniform type, and convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) for i in range(iterations): delta = (numpy.ravel(b - A*x)*numpy.ravel(Dinv)).astype(A.dtype) amg_core.jacobi_ne(A.indptr, A.indices, A.data, x, b, delta, temp, row_start, row_stop, row_step, omega)
def block_jacobi(A, x, b, Dinv=None, blocksize=1, iterations=1, omega=1.0): """Perform block Jacobi iteration on the linear system Ax=b Parameters ---------- A : csr_matrix or bsr_matrix Sparse NxN matrix x : ndarray Approximate solution (length N) b : ndarray Right-hand side (length N) Dinv : array Array holding block diagonal inverses of A size (N/blocksize, blocksize, blocksize) blocksize : int Desired dimension of blocks iterations : int Number of iterations to perform omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. Examples -------- >>> ## Use block Jacobi 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)) >>> block_jacobi(A, x0, b, blocksize=4, iterations=10, omega=1.0) >>> print norm(b-A*x0) 4.66474230129 >>> # >>> ## Use block Jacobi 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=('block_jacobi', {'omega': 4.0/3.0, 'iterations' : 2, 'blocksize' : 4}), ... postsmoother=('block_jacobi', {'omega': 4.0/3.0, 'iterations' : 2, 'blocksize' : 4})) >>> 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=['csr', 'bsr']) A = A.tobsr(blocksize=(blocksize, blocksize)) if Dinv == None: Dinv = get_block_diag(A, blocksize=blocksize, inv_flag=True) elif Dinv.shape[0] != A.shape[0]/blocksize: raise ValueError('Dinv and A have incompatible dimensions') elif (Dinv.shape[1] != blocksize) or (Dinv.shape[2] != blocksize): raise ValueError('Dinv and blocksize are incompatible') sweep = slice(None) (row_start,row_stop,row_step) = sweep.indices(A.shape[0]/blocksize) if (row_stop - row_start) * row_step <= 0: #no work to do return temp = numpy.empty_like(x) # Create uniform type, and convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) for iter in xrange(iterations): amg_core.block_jacobi(A.indptr, A.indices, numpy.ravel(A.data), x, b, numpy.ravel(Dinv), temp, row_start, row_stop, row_step, omega, blocksize)
def jacobi(A, x, b, iterations=1, omega=1.0): """Perform Jacobi iteration on the linear system Ax=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 omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. Examples -------- >>> ## Use Jacobi 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)) >>> jacobi(A, x0, b, iterations=10, omega=1.0) >>> print norm(b-A*x0) 5.83475132751 >>> # >>> ## Use Jacobi 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=('jacobi', {'omega': 4.0/3.0, 'iterations' : 2}), ... postsmoother=('jacobi', {'omega': 4.0/3.0, 'iterations' : 2})) >>> 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=['csr', 'bsr']) sweep = slice(None) (row_start,row_stop,row_step) = sweep.indices(A.shape[0]) if (row_stop - row_start) * row_step <= 0: #no work to do return temp = numpy.empty_like(x) # Create uniform type, and convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) if sparse.isspmatrix_csr(A): for iter in xrange(iterations): amg_core.jacobi(A.indptr, A.indices, A.data, x, b, temp, row_start, row_stop, row_step, omega) else: R,C = A.blocksize if R != C: raise ValueError('BSR blocks must be square') row_start = row_start / R row_stop = row_stop / R for iter in xrange(iterations): amg_core.bsr_jacobi(A.indptr, A.indices, numpy.ravel(A.data), x, b, temp, row_start, row_stop, row_step, R, omega)
def jacobi_ne(A, x, b, iterations=1, omega=1.0): """Perform Jacobi iterations on the linear system A A.H x = A.H b (Also known as Cimmino relaxation) 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 omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. References ---------- .. [1] Brandt, Ta'asan. "Multigrid Method For Nearly Singular And Slightly Indefinite Problems." 1985. NASA Technical Report Numbers: ICASE-85-57; NAS 1.26:178026; NASA-CR-178026; .. [2] Kaczmarz. Angenaeherte Aufloesung von Systemen Linearer Gleichungen. Bull. Acad. Polon. Sci. Lett. A 35, 355-57. 1937 .. [3] Cimmino. La ricerca scientifica ser. II 1. Pubbliz. dell'Inst. pre le Appl. del Calculo 34, 326-333, 1938. Examples -------- >>> ## Use NE Jacobi as a Stand-Alone Solver >>> from pyamg.relaxation import jacobi_ne >>> from pyamg.gallery import poisson >>> from pyamg.util.linalg import norm >>> import numpy >>> A = poisson((50,50), format='csr') >>> x0 = numpy.zeros((A.shape[0],1)) >>> b = numpy.ones((A.shape[0],1)) >>> jacobi_ne(A, x0, b, iterations=10, omega=2.0/3.0) >>> print norm(b-A*x0) 49.3886046066 >>> # >>> ## Use NE Jacobi 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=('jacobi_ne', {'iterations' : 2, 'omega' : 4.0/3.0}), ... postsmoother=('jacobi_ne', {'iterations' : 2, 'omega' : 4.0/3.0})) >>> 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=['csr']) sweep = slice(None) (row_start, row_stop, row_step) = sweep.indices(A.shape[0]) temp = numpy.zeros_like(x) # Dinv for A*A.H Dinv = get_diagonal(A, norm_eq=2, inv=True) # Create uniform type, and convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) for i in range(iterations): delta = (numpy.ravel(b - A * x) * numpy.ravel(Dinv)).astype(A.dtype) amg_core.jacobi_ne(A.indptr, A.indices, A.data, x, b, delta, temp, row_start, row_stop, row_step, omega)
def block_jacobi(A, x, b, Dinv=None, blocksize=1, iterations=1, omega=1.0): """Perform block Jacobi iteration on the linear system Ax=b Parameters ---------- A : csr_matrix or bsr_matrix Sparse NxN matrix x : ndarray Approximate solution (length N) b : ndarray Right-hand side (length N) Dinv : array Array holding block diagonal inverses of A size (N/blocksize, blocksize, blocksize) blocksize : int Desired dimension of blocks iterations : int Number of iterations to perform omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. Examples -------- >>> ## Use block Jacobi 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)) >>> block_jacobi(A, x0, b, blocksize=4, iterations=10, omega=1.0) >>> print norm(b-A*x0) 4.66474230129 >>> # >>> ## Use block Jacobi 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=('block_jacobi', {'omega': 4.0/3.0, 'iterations' : 2, 'blocksize' : 4}), ... postsmoother=('block_jacobi', {'omega': 4.0/3.0, 'iterations' : 2, 'blocksize' : 4})) >>> 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=['csr', 'bsr']) A = A.tobsr(blocksize=(blocksize, blocksize)) if Dinv == None: Dinv = get_block_diag(A, blocksize=blocksize, inv_flag=True) elif Dinv.shape[0] != A.shape[0] / blocksize: raise ValueError('Dinv and A have incompatible dimensions') elif (Dinv.shape[1] != blocksize) or (Dinv.shape[2] != blocksize): raise ValueError('Dinv and blocksize are incompatible') sweep = slice(None) (row_start, row_stop, row_step) = sweep.indices(A.shape[0] / blocksize) if (row_stop - row_start) * row_step <= 0: #no work to do return temp = numpy.empty_like(x) # Create uniform type, and convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) for iter in xrange(iterations): amg_core.block_jacobi(A.indptr, A.indices, numpy.ravel(A.data), x, b, numpy.ravel(Dinv), temp, row_start, row_stop, row_step, omega, blocksize)
def jacobi(A, x, b, iterations=1, omega=1.0): """Perform Jacobi iteration on the linear system Ax=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 omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. Examples -------- >>> ## Use Jacobi 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)) >>> jacobi(A, x0, b, iterations=10, omega=1.0) >>> print norm(b-A*x0) 5.83475132751 >>> # >>> ## Use Jacobi 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=('jacobi', {'omega': 4.0/3.0, 'iterations' : 2}), ... postsmoother=('jacobi', {'omega': 4.0/3.0, 'iterations' : 2})) >>> 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=['csr', 'bsr']) sweep = slice(None) (row_start, row_stop, row_step) = sweep.indices(A.shape[0]) if (row_stop - row_start) * row_step <= 0: #no work to do return temp = numpy.empty_like(x) # Create uniform type, and convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) if sparse.isspmatrix_csr(A): for iter in xrange(iterations): amg_core.jacobi(A.indptr, A.indices, A.data, x, b, temp, row_start, row_stop, row_step, omega) else: R, C = A.blocksize if R != C: raise ValueError('BSR blocks must be square') row_start = row_start / R row_stop = row_stop / R for iter in xrange(iterations): amg_core.bsr_jacobi(A.indptr, A.indices, numpy.ravel(A.data), x, b, temp, row_start, row_stop, row_step, R, omega)
def FC_block_jacobi(A, x, b, Cpts, Fpts, Dinv=None, blocksize=1, iterations=1, F_iterations=1, C_iterations=1, omega=1.0): """Perform FC block Jacobi iteration on the linear system Ax=b, that is x_f = (1-omega)x_f + omega*Dff^{-1}(b_f - Aff*xf - Afc*xc) x_c = (1-omega)x_c + omega*Dff^{-1}(b_c - Acf*xf - Acc*xc) where xf is x restricted to F-blocks, and Dff^{-1} the block inverse of the block diagonal Dff, and likewise for c subscripts. Parameters ---------- A : csr_matrix or bsr_matrix Sparse NxN matrix x : ndarray Approximate solution (length N) b : ndarray Right-hand side (length N) Cpts : array ints List of C-blocks in A Fpts : array ints List of F-blocks in A Dinv : array Array holding block diagonal inverses of A size (N/blocksize, blocksize, blocksize) blocksize : int Desired dimension of blocks iterations : int Number of iterations to perform of total FC-cycle F_iterations : int Number of sweeps of F-relaxation to perform C_iterations : int Number of sweeps of C-relaxation to perform omega : scalar Damping parameter Returns ------- Nothing, x will be modified in place. """ A, x, b = make_system(A, x, b, formats=['csr', 'bsr']) A = A.tobsr(blocksize=(blocksize, blocksize)) if Dinv is None: Dinv = get_block_diag(A, blocksize=blocksize, inv_flag=True) elif Dinv.shape[0] != int(A.shape[0]/blocksize): raise ValueError('Dinv and A have incompatible dimensions') elif (Dinv.shape[1] != blocksize) or (Dinv.shape[2] != blocksize): raise ValueError('Dinv and blocksize are incompatible') # Create uniform type, convert possibly complex scalars to length 1 arrays [omega] = type_prep(A.dtype, [omega]) # Perform block C-relaxation then block F-relaxation for iter in range(iterations): for Fiter in range(F_iterations): amg_core.block_jacobi_indexed(A.indptr, A.indices, np.ravel(A.data), x, b, np.ravel(Dinv), Fpts, omega, blocksize) for Citer in range(C_iterations): amg_core.block_jacobi_indexed(A.indptr, A.indices, np.ravel(A.data), x, b, np.ravel(Dinv), Cpts, omega, blocksize)