def test_preconditioners(): atol = 1e-6 index = 1 scale = 0.2 name = f"GT{index:02d}" # print(name) image_dir = "data" image = load_image(f"{image_dir}/input_training_lowres/{name}.png", "rgb", scale, "bilinear") trimap = load_image( f"{image_dir}/trimap_training_lowres/Trimap1/{name}.png", "gray", scale, "nearest", ) A, b = make_linear_system(cf_laplacian(image), trimap) preconditioners = [ ("no", lambda A: None), ("jacobi", lambda A: jacobi(A)), ("icholt", lambda A: ichol(A, max_nnz=500000)), ("vcycle", lambda A: vcycle(A, trimap.shape)), ] expected_iterations = { "no": 532, "jacobi": 250, "icholt": 3, "vcycle": 88, } for preconditioner_name, preconditioner in preconditioners: callback = CounterCallback() M = preconditioner(A) x = cg(A, b, M=M, atol=atol, rtol=0, maxiter=10000, callback=callback) r = b - A.dot(x) norm_r = np.linalg.norm(r) assert norm_r <= atol n_expected = expected_iterations[preconditioner_name] if callback.n > n_expected: print( "WARNING: Unexpected number of iterations. Expected %d, but got %d" % (n_expected, callback.n)) assert callback.n <= n_expected
def test_ichol(): np.random.seed(0) for _ in range(10): n = 50 A = np.random.rand(n, n) A[np.random.rand(n, n) < 0.8] = 0 A += A.T + n * np.eye(n) A = scipy.sparse.csc_matrix(A) decomposition = ichol(A, discard_threshold=0.0, max_nnz=100000) x_true = np.random.rand(n) b = A.dot(x_true) x = decomposition(b) error = np.linalg.norm(x - x_true) assert error < 1e-10
def build_solver(solver_name, A, Acsr, Acsc, Acoo, AL, b, atol, rtol): # Construct a solver from matrix A and vector b. if solver_name == "cg_icholt": from pymatting import cg, ichol M = ichol(A, discard_threshold=1e-3, shifts=[0.002]) return lambda: cg(A, b, M=M, atol=atol, rtol=0) if solver_name == "pyamg": import pyamg from pymatting import cg M = pyamg.smoothed_aggregation_solver(A).aspreconditioner() return lambda: cg(Acsr, b, M=M, atol=atol, rtol=0) if solver_name == "mumps": from solve_mumps import solve_mumps_coo, init_mpi, finalize_mpi init_mpi() return lambda: solve_mumps_coo( AL.data, AL.row, AL.col, b, is_symmetric=True) if solver_name == "petsc": from solve_petsc import solve_petsc_coo, init_petsc, finalize_petsc init_petsc() return lambda: solve_petsc_coo( Acoo.data, Acoo.row, Acoo.col, b, atol=atol, gamg_threshold=0.1) if solver_name == "amgcl": from solve_amgcl import solve_amgcl_csr return lambda: solve_amgcl_csr( Acsr.data, Acsr.indices, Acsr.indptr, b, atol=atol, rtol=0) if solver_name == "umfpack": # Alternatively: # return lambda: scipy.sparse.linalg.spsolve(Acsc, b, use_umfpack=True) import scikits.umfpack return lambda: scikits.umfpack.spsolve(A, b) if solver_name == "superlu": # Alternatively: # scipy.sparse.linalg.spsolve(A, b, use_umfpack=False) return lambda: scipy.sparse.linalg.splu(Acsc).solve(b) if solver_name == "eigen_cholesky": from solve_eigen import solve_eigen_cholesky_coo return lambda: solve_eigen_cholesky_coo(Acoo.data, Acoo.row, Acoo.col, b) if solver_name == "eigen_icholt": from solve_eigen import solve_eigen_icholt_coo # Choose shift hust large enough to not fail for given images # (might fail with larger/different images) initial_shift = 5e-4 return lambda: solve_eigen_icholt_coo(Acoo.data, Acoo.row, Acoo.col, b, rtol=rtol, initial_shift=initial_shift) raise ValueError(f"Solver {solver_name} does not exist.")
def solve_cg_icholt(A, b, atol): M = ichol(A, discard_threshold=1e-3, shifts=[0.002]) return cg(A, b, M=M, atol=atol, rtol=0)