def test_coarse_solver_opts(self): # these tests are meant to test whether coarse solvers are correctly # passed parameters A = poisson((30, 30), format='csr') b = np.random.rand(A.shape[0], 1) # for each pair, the first entry should yield an SA solver that # converges in fewer iterations for a basic Poisson problem coarse_solver_pairs = [(('jacobi', {'iterations': 30}), 'jacobi')] coarse_solver_pairs.append((('gauss_seidel', {'iterations': 30}), 'gauss_seidel')) coarse_solver_pairs.append(('gauss_seidel', 'jacobi')) coarse_solver_pairs.append(('cg', ('cg', {'tol': 10.0}))) # scipy >= 1.7: pinv takes 'rtol' # scipy < 1.7: pinv takes 'cond' kword = 'rtol' if kword not in sla.pinv.__code__.co_varnames: kword = 'cond' coarse_solver_pairs.append(('pinv', ('pinv', {kword: 1.0}))) for coarse1, coarse2 in coarse_solver_pairs: r1 = [] r2 = [] sa1 = rootnode_solver(A, coarse_solver=coarse1, max_coarse=500) sa2 = rootnode_solver(A, coarse_solver=coarse2, max_coarse=500) x1 = sa1.solve(b, residuals=r1) x2 = sa2.solve(b, residuals=r2) del x1, x2 assert((len(r1) + 5) < len(r2))
def test_coarse_solver_opts(self): # these tests are meant to test whether coarse solvers are correctly # passed parameters A = poisson((30, 30), format='csr') b = sp.rand(A.shape[0], 1) # for each pair, the first entry should yield an SA solver that # converges in fewer iterations for a basic Poisson problem coarse_solver_pairs = [(('jacobi', {'iterations': 30}), 'jacobi')] coarse_solver_pairs.append((('gauss_seidel', {'iterations': 30}), 'gauss_seidel')) coarse_solver_pairs.append(('gauss_seidel', 'jacobi')) coarse_solver_pairs.append(('cg', ('cg', {'tol': 10.0}))) coarse_solver_pairs.append(('pinv2', ('pinv2', {'cond': 1.0}))) for coarse1, coarse2 in coarse_solver_pairs: r1 = [] r2 = [] sa1 = rootnode_solver(A, coarse_solver=coarse1) sa2 = rootnode_solver(A, coarse_solver=coarse2) x1 = sa1.solve(b, residuals=r1) x2 = sa2.solve(b, residuals=r2) del x1, x2 assert((len(r1) + 5) < len(r2))
def test_nonsymmetric(self): # problem data data = load_example('recirc_flow') A = data['A'].tocsr() B = data['B'] numpy.random.seed(625) x0 = scipy.rand(A.shape[0]) b = A * scipy.rand(A.shape[0]) # solver parameters smooth = ('energy', {'krylov': 'gmres'}) SA_build_args = {'max_coarse': 25, 'coarse_solver': 'pinv2', 'symmetry': 'nonsymmetric'} SA_solve_args = {'cycle': 'V', 'maxiter': 20, 'tol': 1e-8} strength = [('evolution', {'k': 2, 'epsilon': 8.0})] smoother = ('gauss_seidel_nr', {'sweep': 'symmetric', 'iterations': 1}) improve_candidates = [('gauss_seidel_nr', {'sweep': 'symmetric', 'iterations': 4}), None] # Construct solver with nonsymmetric parameters sa = rootnode_solver(A, B=B, smooth=smooth, improve_candidates=improve_candidates, strength=strength, presmoother=smoother, postsmoother=smoother, **SA_build_args) residuals = [] # stand-alone solve x = sa.solve(b, x0=x0, residuals=residuals, **SA_solve_args) residuals = array(residuals) avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 1 %1.3e, %1.3e" % (avg_convergence_ratio, 0.7) assert(avg_convergence_ratio < 0.7) # accelerated solve residuals = [] x = sa.solve(b, x0=x0, residuals=residuals, accel='gmres', **SA_solve_args) residuals = array(residuals) avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 2 %1.3e, %1.3e" % (avg_convergence_ratio, 0.45) assert(avg_convergence_ratio < 0.45) # test that nonsymmetric parameters give the same result as symmetric # parameters for Poisson problem A = poisson((15, 15), format='csr') strength = 'symmetric' SA_build_args['symmetry'] = 'nonsymmetric' sa_nonsymm = rootnode_solver(A, B=ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args) SA_build_args['symmetry'] = 'symmetric' sa_symm = rootnode_solver(A, B=ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args) for (symm_lvl, nonsymm_lvl) in zip(sa_nonsymm.levels, sa_symm.levels): assert_array_almost_equal(symm_lvl.A.todense(), nonsymm_lvl.A.todense())
def test_nonsymmetric(self): # problem data data = load_example('recirc_flow') A = data['A'].tocsr() B = data['B'] numpy.random.seed(625) x0 = scipy.rand(A.shape[0]) b = A * scipy.rand(A.shape[0]) # solver parameters smooth = ('energy', {'krylov': 'gmres'}) SA_build_args = { 'max_coarse': 25, 'coarse_solver': 'pinv2', 'symmetry': 'nonsymmetric' } SA_solve_args = {'cycle': 'V', 'maxiter': 20, 'tol': 1e-8} strength = [('evolution', {'k': 2, 'epsilon': 8.0})] smoother = ('gauss_seidel_nr', {'sweep': 'symmetric', 'iterations': 1}) improve_candidates = [('gauss_seidel_nr', { 'sweep': 'symmetric', 'iterations': 4 }), None] # Construct solver with nonsymmetric parameters sa = rootnode_solver(A, B=B, smooth=smooth, improve_candidates=improve_candidates, \ strength=strength, presmoother=smoother, postsmoother=smoother, **SA_build_args) residuals = [] # stand-alone solve x = sa.solve(b, x0=x0, residuals=residuals, **SA_solve_args) residuals = array(residuals) avg_convergence_ratio = (residuals[-1] / residuals[0])**(1.0 / len(residuals)) #print "Test 1 %1.3e, %1.3e" % (avg_convergence_ratio, 0.7) assert (avg_convergence_ratio < 0.7) # accelerated solve residuals = [] x = sa.solve(b, x0=x0, residuals=residuals, accel='gmres', **SA_solve_args) residuals = array(residuals) avg_convergence_ratio = (residuals[-1] / residuals[0])**(1.0 / len(residuals)) #print "Test 2 %1.3e, %1.3e" % (avg_convergence_ratio, 0.45) assert (avg_convergence_ratio < 0.45) # test that nonsymmetric parameters give the same result as symmetric parameters # for Poisson problem A = poisson((15, 15), format='csr') strength = 'symmetric' SA_build_args['symmetry'] = 'nonsymmetric' sa_nonsymm = rootnode_solver(A, B=ones((A.shape[0],1)), smooth=smooth, \ strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None,**SA_build_args) SA_build_args['symmetry'] = 'symmetric' sa_symm = rootnode_solver(A, B=ones((A.shape[0],1)), smooth=smooth, \ strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None,**SA_build_args) for (symm_lvl, nonsymm_lvl) in zip(sa_nonsymm.levels, sa_symm.levels): assert_array_almost_equal(symm_lvl.A.todense(), nonsymm_lvl.A.todense())
def test_nonhermitian(self): # problem data data = load_example('helmholtz_2D') A = data['A'].tocsr() B = data['B'] np.random.seed(625) x0 = sp.rand(A.shape[0]) + 1.0j * sp.rand(A.shape[0]) b = A * sp.rand(A.shape[0]) + 1.0j * (A * sp.rand(A.shape[0])) # solver parameters smooth = ('energy', {'krylov': 'gmres'}) SA_build_args = {'max_coarse': 25, 'coarse_solver': 'pinv2', 'symmetry': 'symmetric'} SA_solve_args = {'cycle': 'V', 'maxiter': 20, 'tol': 1e-8} strength = [('evolution', {'k': 2, 'epsilon': 2.0})] smoother = ('gauss_seidel_nr', {'sweep': 'symmetric', 'iterations': 1}) # Construct solver with nonsymmetric parameters sa = rootnode_solver(A, B=B, smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, **SA_build_args) residuals = [] # stand-alone solve x = sa.solve(b, x0=x0, residuals=residuals, **SA_solve_args) residuals = np.array(residuals) avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 3 %1.3e, %1.3e" % (avg_convergence_ratio, 0.92) assert(avg_convergence_ratio < 0.92) # accelerated solve residuals = [] x = sa.solve(b, x0=x0, residuals=residuals, accel='gmres', **SA_solve_args) del x residuals = np.array(residuals) avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 4 %1.3e, %1.3e" % (avg_convergence_ratio, 0.8) assert(avg_convergence_ratio < 0.8) # test that nonsymmetric parameters give the same result as symmetric # parameters for the complex-symmetric matrix A strength = 'symmetric' SA_build_args['symmetry'] = 'nonsymmetric' sa_nonsymm = rootnode_solver(A, B=np.ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args) SA_build_args['symmetry'] = 'symmetric' sa_symm = rootnode_solver(A, B=np.ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args) for (symm_lvl, nonsymm_lvl) in zip(sa_nonsymm.levels, sa_symm.levels): assert_array_almost_equal(symm_lvl.A.todense(), nonsymm_lvl.A.todense())
def test_matrix_formats(self): # Do dense, csr, bsr and csc versions of A all yield the same solver A = poisson((7, 7), format="csr") cases = [A.tobsr(blocksize=(1, 1))] cases.append(A.tocsc()) cases.append(A.todense()) sa_old = rootnode_solver(A, max_coarse=10) for AA in cases: sa_new = rootnode_solver(AA, max_coarse=10) assert abs(ravel(sa_old.levels[-1].A.todense() - sa_new.levels[-1].A.todense())).max() < 0.01 sa_old = sa_new
def test_matrix_formats(self): # Do dense, csr, bsr and csc versions of A all yield the same solver A = poisson((7, 7), format='csr') cases = [A.tobsr(blocksize=(1, 1))] cases.append(A.tocsc()) cases.append(A.todense()) sa_old = rootnode_solver(A, max_coarse=10) for AA in cases: sa_new = rootnode_solver(AA, max_coarse=10) dff = sa_old.levels[-1].A.todense() - sa_new.levels[-1].A.todense() assert(np.abs(np.ravel(dff)).max() < 0.01) sa_old = sa_new
def test_improve_candidates(self): # test improve_candidates for the Poisson problem and elasticity, where # rho_scale is the amount that each successive improve_candidates # option should improve convergence over the previous # improve_candidates option. improve_candidates_list = [None, [("block_gauss_seidel", {"iterations": 4, "sweep": "symmetric"})]] # make tests repeatable numpy.random.seed(0) cases = [] A_elas, B_elas = linear_elasticity((60, 60), format="bsr") # Matrix Candidates rho_scale cases.append((poisson((75, 75), format="csr"), ones((75 * 75, 1)), 0.9)) cases.append((A_elas, B_elas, 0.9)) for (A, B, rho_scale) in cases: last_rho = -1.0 x0 = rand(A.shape[0], 1) b = rand(A.shape[0], 1) for improve_candidates in improve_candidates_list: ml = rootnode_solver(A, B, max_coarse=10, improve_candidates=improve_candidates) residuals = [] x_sol = ml.solve(b, x0=x0, maxiter=20, tol=1e-10, residuals=residuals) del x_sol rho = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) if last_rho == -1.0: last_rho = rho else: # each successive improve_candidates option should be an # improvement on the previous print "\nimprove_candidates # Test: %1.3e, %1.3e, # %d\n"%(rho,rho_scale*last_rho,A.shape[0]) assert rho < rho_scale * last_rho last_rho = rho
def test_basic(self): """check that method converges at a reasonable rate""" for A, B, c_factor, symmetry, smooth in self.cases: A = csr_matrix(A) ml = rootnode_solver(A, B, symmetry=symmetry, smooth=smooth, max_coarse=10) numpy.random.seed(0) # make tests repeatable x = rand(A.shape[0]) + 1.0j * rand(A.shape[0]) b = A * rand(A.shape[0]) residuals = [] x_sol = ml.solve(b, x0=x, maxiter=20, tol=1e-10, residuals=residuals) avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Complex Test: %1.3e, %1.3e, %d, %1.3e" % \ # (avg_convergence_ratio, c_factor, len(ml.levels), # ml.operator_complexity()) assert(avg_convergence_ratio < c_factor)
def test_DAD(self): A = poisson((50, 50), format="csr") x = sp.rand(A.shape[0]) b = sp.rand(A.shape[0]) D = diag_sparse(1.0 / np.sqrt(10 ** (12 * sp.rand(A.shape[0]) - 6))) D = D.tocsr() D_inv = diag_sparse(1.0 / D.data) # DAD = D * A * D B = np.ones((A.shape[0], 1)) # TODO force 2 level method and check that result is the same kwargs = {"max_coarse": 1, "max_levels": 2, "coarse_solver": "splu"} sa = rootnode_solver(D * A * D, D_inv * B, **kwargs) residuals = [] x_sol = sa.solve(b, x0=x, maxiter=10, tol=1e-12, residuals=residuals) del x_sol avg_convergence_ratio = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Diagonal Scaling Test: %1.3e, %1.3e" % # (avg_convergence_ratio, 0.4) assert avg_convergence_ratio < 0.4
def test_symmetry(self): # Test that a basic V-cycle yields a symmetric linear operator. Common # reasons for failure are problems with using the same rho for the # pres/post-smoothers and using the same block_D_inv for # pre/post-smoothers. n = 500 A = poisson((n,), format='csr') smoothers = [('gauss_seidel', {'sweep': 'symmetric'}), ('schwarz', {'sweep': 'symmetric'}), ('block_gauss_seidel', {'sweep': 'symmetric'}), 'jacobi', 'block_jacobi'] Bs = [ones((n, 1)), hstack((ones((n, 1)), arange(1, n + 1, dtype='float').reshape(-1, 1)))] for smoother in smoothers: for B in Bs: ml = rootnode_solver(A, B, max_coarse=10, presmoother=smoother, postsmoother=smoother) P = ml.aspreconditioner() x = rand(n,) y = rand(n,) assert_approx_equal(dot(P * x, y), dot(x, P * y))
def test_symmetry(self): # Test that a basic V-cycle yields a symmetric linear operator. Common # reasons for failure are problems with using the same rho for the # pres/post-smoothers and using the same block_D_inv for # pre/post-smoothers. n = 500 A = poisson((n,), format='csr') smoothers = [('gauss_seidel', {'sweep': 'symmetric'}), ('schwarz', {'sweep': 'symmetric'}), ('block_gauss_seidel', {'sweep': 'symmetric'}), 'jacobi', 'block_jacobi'] Bs = [np.ones((n, 1)), sp.hstack((np.ones((n, 1)), np.arange(1, n + 1, dtype='float').reshape(-1, 1)))] for smoother in smoothers: for B in Bs: ml = rootnode_solver(A, B, max_coarse=10, presmoother=smoother, postsmoother=smoother) P = ml.aspreconditioner() x = sp.rand(n,) y = sp.rand(n,) assert_approx_equal(np.dot(P * x, y), np.dot(x, P * y))
def test_DAD(self): A = poisson((50, 50), format='csr') x = rand(A.shape[0]) b = rand(A.shape[0]) D = diag_sparse(1.0 / sqrt(10 ** (12 * rand(A.shape[0]) - 6))).tocsr() D_inv = diag_sparse(1.0 / D.data) DAD = D * A * D B = ones((A.shape[0], 1)) # TODO force 2 level method and check that result is the same kwargs = {'max_coarse': 1, 'max_levels': 2, 'coarse_solver': 'splu'} sa = rootnode_solver(D * A * D, D_inv * B, **kwargs) residuals = [] x_sol = sa.solve(b, x0=x, maxiter=10, tol=1e-12, residuals=residuals) avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Diagonal Scaling Test: %1.3e, %1.3e" % # (avg_convergence_ratio, 0.4) assert(avg_convergence_ratio < 0.4)
def test_basic(self): """check that method converges at a reasonable rate""" for A, B, c_factor, symmetry, smooth in self.cases: A = csr_matrix(A) ml = rootnode_solver(A, B, symmetry=symmetry, smooth=smooth, max_coarse=10) np.random.seed(0) # make tests repeatable x = sp.rand(A.shape[0]) + 1.0j * sp.rand(A.shape[0]) b = A * sp.rand(A.shape[0]) residuals = [] x_sol = ml.solve(b, x0=x, maxiter=20, tol=1e-10, residuals=residuals) del x_sol avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Complex Test: %1.3e, %1.3e, %d, %1.3e" % \ # (avg_convergence_ratio, c_factor, len(ml.levels), # ml.operator_complexity()) assert(avg_convergence_ratio < c_factor)
def test_DAD(self): A = poisson((50, 50), format='csr') x = sp.rand(A.shape[0]) b = sp.rand(A.shape[0]) D = diag_sparse(1.0 / np.sqrt(10**(12 * sp.rand(A.shape[0]) - 6))).tocsr() D_inv = diag_sparse(1.0 / D.data) # DAD = D * A * D B = np.ones((A.shape[0], 1)) # TODO force 2 level method and check that result is the same kwargs = {'max_coarse': 1, 'max_levels': 2, 'coarse_solver': 'splu'} sa = rootnode_solver(D * A * D, D_inv * B, **kwargs) residuals = [] x_sol = sa.solve(b, x0=x, maxiter=10, tol=1e-12, residuals=residuals) del x_sol avg_convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Diagonal Scaling Test: %1.3e, %1.3e" % # (avg_convergence_ratio, 0.4) assert(avg_convergence_ratio < 0.4)
def run_cases(self, opts): for A, B in self.cases: ml = rootnode_solver(A, B, max_coarse=5, **opts) numpy.random.seed(0) # make tests repeatable x = rand(A.shape[0]) b = A * rand(A.shape[0]) residuals = [] x_sol = ml.solve(b, x0=x, maxiter=30, tol=1e-10, residuals=residuals) del x_sol convergence_ratio = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) assert convergence_ratio < 0.9
def test_coarse_solver_opts(self): # these tests are meant to test whether coarse solvers are correctly # passed parameters A = poisson((30, 30), format="csr") b = rand(A.shape[0], 1) # for each pair, the first entry should yield an SA solver that # converges in fewer iterations for a basic Poisson problem coarse_solver_pairs = [(("jacobi", {"iterations": 30}), "jacobi")] coarse_solver_pairs.append((("gauss_seidel", {"iterations": 30}), "gauss_seidel")) coarse_solver_pairs.append(("gauss_seidel", "jacobi")) coarse_solver_pairs.append(("cg", ("cg", {"tol": 10.0}))) coarse_solver_pairs.append(("pinv2", ("pinv2", {"cond": 1.0}))) for coarse1, coarse2 in coarse_solver_pairs: r1 = [] r2 = [] sa1 = rootnode_solver(A, coarse_solver=coarse1) sa2 = rootnode_solver(A, coarse_solver=coarse2) x1 = sa1.solve(b, residuals=r1) x2 = sa2.solve(b, residuals=r2) del x1, x2 assert (len(r1) + 5) < len(r2)
def run_cases(self, opts): for A, B in self.cases: ml = rootnode_solver(A, B, max_coarse=5, **opts) np.random.seed(0) # make tests repeatable x = sp.rand(A.shape[0]) b = A * sp.rand(A.shape[0]) residuals = [] x_sol = ml.solve(b, x0=x, maxiter=30, tol=1e-10, residuals=residuals) del x_sol convergence_ratio =\ (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) assert(convergence_ratio < 0.9)
def test_improve_candidates(self): # test improve_candidates for the Poisson problem and elasticity, where # rho_scale is the amount that each successive improve_candidates # option should improve convergence over the previous # improve_candidates option. improve_candidates_list = [ None, [('block_gauss_seidel', { 'iterations': 4, 'sweep': 'symmetric' })] ] # make tests repeatable np.random.seed(0) cases = [] A_elas, B_elas = linear_elasticity((60, 60), format='bsr') # Matrix Candidates rho_scale cases.append((poisson((75, 75), format='csr'), np.ones( (75 * 75, 1)), 0.9)) cases.append((A_elas, B_elas, 0.9)) for (A, B, rho_scale) in cases: last_rho = -1.0 x0 = np.random.rand(A.shape[0], 1) b = np.random.rand(A.shape[0], 1) for improve_candidates in improve_candidates_list: ml = rootnode_solver(A, B, max_coarse=10, improve_candidates=improve_candidates) residuals = [] x_sol = ml.solve(b, x0=x0, maxiter=20, tol=1e-10, residuals=residuals) del x_sol rho = (residuals[-1] / residuals[0])**(1.0 / len(residuals)) if last_rho == -1.0: last_rho = rho else: # each successive improve_candidates option should be an # improvement on the previous print "\nimprove_candidates # Test: %1.3e, %1.3e, # %d\n"%(rho,rho_scale*last_rho,A.shape[0]) assert (rho < rho_scale * last_rho) last_rho = rho
def test_symmetry(self): # Test that a basic V-cycle yields a symmetric linear operator. Common # reasons for failure are problems with using the same rho for the # pres/post-smoothers and using the same block_D_inv for # pre/post-smoothers. n = 500 A = poisson((n,), format="csr") smoothers = [ ("gauss_seidel", {"sweep": "symmetric"}), ("schwarz", {"sweep": "symmetric"}), ("block_gauss_seidel", {"sweep": "symmetric"}), "jacobi", "block_jacobi", ] Bs = [np.ones((n, 1)), sp.hstack((np.ones((n, 1)), np.arange(1, n + 1, dtype="float").reshape(-1, 1)))] for smoother in smoothers: for B in Bs: ml = rootnode_solver(A, B, max_coarse=10, presmoother=smoother, postsmoother=smoother) P = ml.aspreconditioner() x = sp.rand(n) y = sp.rand(n) assert_approx_equal(np.dot(P * x, y), np.dot(x, P * y))
def test_nonsymmetric(self): # problem data data = load_example("recirc_flow") A = data["A"].tocsr() B = data["B"] np.random.seed(625) x0 = sp.rand(A.shape[0]) b = A * sp.rand(A.shape[0]) # solver parameters smooth = ("energy", {"krylov": "gmres"}) SA_build_args = {"max_coarse": 25, "coarse_solver": "pinv2", "symmetry": "nonsymmetric"} SA_solve_args = {"cycle": "V", "maxiter": 20, "tol": 1e-8} strength = [("evolution", {"k": 2, "epsilon": 8.0})] smoother = ("gauss_seidel_nr", {"sweep": "symmetric", "iterations": 1}) improve_candidates = [("gauss_seidel_nr", {"sweep": "symmetric", "iterations": 4}), None] # Construct solver with nonsymmetric parameters sa = rootnode_solver( A, B=B, smooth=smooth, improve_candidates=improve_candidates, strength=strength, presmoother=smoother, postsmoother=smoother, **SA_build_args ) residuals = [] # stand-alone solve x = sa.solve(b, x0=x0, residuals=residuals, **SA_solve_args) residuals = np.array(residuals) avg_convergence_ratio = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 1 %1.3e, %1.3e" % (avg_convergence_ratio, 0.7) assert avg_convergence_ratio < 0.7 # accelerated solve residuals = [] x = sa.solve(b, x0=x0, residuals=residuals, accel="gmres", **SA_solve_args) del x residuals = np.array(residuals) avg_convergence_ratio = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 2 %1.3e, %1.3e" % (avg_convergence_ratio, 0.45) assert avg_convergence_ratio < 0.45 # test that nonsymmetric parameters give the same result as symmetric # parameters for Poisson problem A = poisson((15, 15), format="csr") strength = "symmetric" SA_build_args["symmetry"] = "nonsymmetric" sa_nonsymm = rootnode_solver( A, B=np.ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args ) SA_build_args["symmetry"] = "symmetric" sa_symm = rootnode_solver( A, B=np.ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args ) for (symm_lvl, nonsymm_lvl) in zip(sa_nonsymm.levels, sa_symm.levels): assert_array_almost_equal(symm_lvl.A.todense(), nonsymm_lvl.A.todense())
x0 = np.zeros(vec_size, 1) # ----------------------------------------------------------------------------- # # ----------------------------------------------------------------------------- # # Classical root node solver # -------------------------- # Form classical root node multilevel solver object start = time.clock() ml_rn = rootnode_solver(A, B=None, symmetry=symmetry, strength=strength_connection, aggregate=aggregation, smooth=interp_smooth, max_levels=max_levels, max_coarse=max_coarse, presmoother=relaxation, postsmoother=relaxation, improve_candidates=improve_candidates, keep=keep_levels) sol = ml_rn.solve(b, x0, tol, residuals=rn_residuals, cycle=cycle, accel=accel) end = time.clock() nii_time = end - start setup_cost = setup_complexity(sa=ml_rn, strength=strength_connection, smooth=interp_smooth, improve_candidates=improve_candidates, aggregate=aggregation,
def test_nonhermitian(self): # problem data data = load_example("helmholtz_2D") A = data["A"].tocsr() B = data["B"] numpy.random.seed(625) x0 = scipy.rand(A.shape[0]) + 1.0j * scipy.rand(A.shape[0]) b = A * scipy.rand(A.shape[0]) + 1.0j * (A * scipy.rand(A.shape[0])) # solver parameters smooth = ("energy", {"krylov": "gmres"}) SA_build_args = {"max_coarse": 25, "coarse_solver": "pinv2", "symmetry": "symmetric"} SA_solve_args = {"cycle": "V", "maxiter": 20, "tol": 1e-8} strength = [("evolution", {"k": 2, "epsilon": 2.0})] smoother = ("gauss_seidel_nr", {"sweep": "symmetric", "iterations": 1}) # Construct solver with nonsymmetric parameters sa = rootnode_solver( A, B=B, smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, **SA_build_args ) residuals = [] # stand-alone solve x = sa.solve(b, x0=x0, residuals=residuals, **SA_solve_args) residuals = array(residuals) avg_convergence_ratio = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 3 %1.3e, %1.3e" % (avg_convergence_ratio, 0.92) assert avg_convergence_ratio < 0.92 # accelerated solve residuals = [] x = sa.solve(b, x0=x0, residuals=residuals, accel="gmres", **SA_solve_args) del x residuals = array(residuals) avg_convergence_ratio = (residuals[-1] / residuals[0]) ** (1.0 / len(residuals)) # print "Test 4 %1.3e, %1.3e" % (avg_convergence_ratio, 0.8) assert avg_convergence_ratio < 0.8 # test that nonsymmetric parameters give the same result as symmetric # parameters for the complex-symmetric matrix A strength = "symmetric" SA_build_args["symmetry"] = "nonsymmetric" sa_nonsymm = rootnode_solver( A, B=ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args ) SA_build_args["symmetry"] = "symmetric" sa_symm = rootnode_solver( A, B=ones((A.shape[0], 1)), smooth=smooth, strength=strength, presmoother=smoother, postsmoother=smoother, improve_candidates=None, **SA_build_args ) for (symm_lvl, nonsymm_lvl) in zip(sa_nonsymm.levels, sa_symm.levels): assert_array_almost_equal(symm_lvl.A.todense(), nonsymm_lvl.A.todense())