def setUp(self):
        self.cases = []

        # Test 1
        A = poisson((5000,), format="csr")
        Ai = A + 1.0j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((Ai, None, 0.12, "symmetric", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((Ai, None, 0.12, "symmetric", ("energy", {"krylov": "gmres"})))

        # Test 2
        A = poisson((71, 71), format="csr")
        Ai = A + (0.625 / 0.01) * 1j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((Ai, None, 1e-3, "symmetric", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((Ai, None, 1e-3, "symmetric", ("energy", {"krylov": "cgnr"})))

        # Test 3
        A = poisson((60, 60), format="csr")
        Ai = 1.0j * A
        self.cases.append((Ai, None, 0.3, "symmetric", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((Ai, None, 0.6, "symmetric", ("energy", {"krylov": "cgnr", "maxiter": 8})))
        self.cases.append((Ai, None, 0.6, "symmetric", ("energy", {"krylov": "gmres", "maxiter": 8})))

        # Test 4
        # Use an "inherently" imaginary problem, the Gauge Laplacian in 2D from
        # Quantum Chromodynamics,
        A = gauge_laplacian(70, spacing=1.0, beta=0.41)
        self.cases.append((A, None, 0.4, "hermitian", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((A, None, 0.4, "hermitian", ("energy", {"krylov": "cg"})))
Example #2
0
    def test_coarse_grid_solver(self):
        cases = []

        cases.append(csr_matrix(diag(arange(1, 5, dtype=float))))
        cases.append(poisson((4,), format='csr'))
        cases.append(poisson((4, 4), format='csr'))

        from pyamg.krylov import cg

        def fn(A, b):
            return cg(A, b)[0]

        # method should be almost exact for small matrices
        for A in cases:
            for solver in ['splu', 'pinv', 'pinv2', 'lu', 'cholesky',
                           'cg', fn]:
                s = coarse_grid_solver(solver)

                b = arange(A.shape[0], dtype=A.dtype)

                x = s(A, b)
                assert_almost_equal(A*x, b)

                # subsequent calls use cached data
                x = s(A, b)
                assert_almost_equal(A*x, b)
Example #3
0
    def setUp(self):
        self.cases = []

        A = poisson((5000,), format='csr')
        self.cases.append((A, None, 0.4, 'symmetric',
                           ('jacobi', {'omega': 4.0 / 3.0})))
        self.cases.append((A, None, 0.4, 'symmetric',
                           ('energy', {'krylov': 'cg'})))
        self.cases.append((A, None, 0.5, 'symmetric',
                           ('energy', {'krylov': 'gmres'})))

        A = poisson((60, 60), format='csr')
        self.cases.append((A, None, 0.42, 'symmetric',
                           ('jacobi', {'omega': 4.0 / 3.0})))
        self.cases.append((A, None, 0.42, 'symmetric',
                           ('energy', {'krylov': 'cg'})))
        self.cases.append((A, None, 0.42, 'symmetric',
                           ('energy', {'krylov': 'cgnr'})))

        A, B = linear_elasticity((50, 50), format='bsr')
        self.cases.append((A, B, 0.32, 'symmetric',
                           ('jacobi', {'omega': 4.0 / 3.0})))
        self.cases.append((A, B, 0.22, 'symmetric',
                           ('energy', {'krylov': 'cg'})))
        self.cases.append((A, B, 0.42, 'symmetric',
                           ('energy', {'krylov': 'cgnr'})))
        self.cases.append((A, B, 0.42, 'symmetric',
                           ('energy', {'krylov': 'gmres'})))
Example #4
0
    def setUp(self):
        self.cases = []

        # Test 1
        A = poisson((5000,), format='csr')
        Ai = A + 1.0j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((Ai, None, 0.12, 'symmetric',
                           ('energy', {'krylov': 'gmres'})))

        # Test 2
        A = poisson((71, 71), format='csr')
        Ai = A + (0.625 / 0.01) * 1.0j *\
            scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((Ai, None, 1e-3, 'symmetric',
                           ('energy', {'krylov': 'cgnr'})))

        # Test 3
        A = poisson((60, 60), format='csr')
        Ai = 1.0j * A
        self.cases.append((Ai, None, 0.35, 'symmetric',
                           ('energy', {'krylov': 'cgnr', 'maxiter': 8})))
        self.cases.append((Ai, None, 0.35, 'symmetric',
                           ('energy', {'krylov': 'gmres', 'maxiter': 8})))

        # Test 4 Use an "inherently" imaginary problem, the Gauge Laplacian in
        # 2D from Quantum Chromodynamics,
        A = gauge_laplacian(70, spacing=1.0, beta=0.41)
        self.cases.append((A, None, 0.25, 'hermitian',
                           ('energy', {'krylov': 'cg'})))
Example #5
0
 def setUp(self):
     self.cases = []
     
     # Consider "Helmholtz" like problems with an imaginary shift so that the operator 
     #   should still be SPD in a sense and SA should perform well.
     # There are better near nullspace vectors than the default, 
     #   but a constant should give a convergent solver, nonetheless.
     A = poisson( (100,),  format='csr'); A = A + 1.0j*scipy.sparse.eye(A.shape[0], A.shape[1])
     self.cases.append((A, None))
     A = poisson( (10,10),  format='csr'); A = A + 1.0j*scipy.sparse.eye(A.shape[0], A.shape[1])
     self.cases.append((A, None))
Example #6
0
    def setUp(self):
        self.cases = []

        # Poisson problems in 1D and 2D
        N = 20
        self.cases.append((poisson((2*N,), format='csr'), rand(2*N,)))     # 0
        self.cases.append((poisson((N, N), format='csr'), rand(N*N,)))  # 1
        # Boxed examples
        A = load_example('recirc_flow')['A'].tocsr()                      # 2
        self.cases.append((A, rand(A.shape[0],)))
        A = load_example('bar')['A'].tobsr(blocksize=(3, 3))               # 3
        self.cases.append((A, rand(A.shape[0],)))
    def setUp(self):
        self.cases = []

        # Poisson problems in 1D and 2D
        for N in [2, 3, 5, 7, 10, 11, 19]:
            self.cases.append(poisson((N,), format='csr'))
        for N in [2, 3, 7, 9]:
            self.cases.append(poisson((N, N), format='csr'))

        for name in ['knot', 'airfoil', 'bar']:
            ex = load_example(name)
            self.cases.append(ex['A'].tocsr())
Example #8
0
    def setUp(self):
        self.cases = []

        # Consider "Helmholtz" like problems with an imaginary shift so that
        # the operator should still be SPD in a sense and SA should perform
        # well.  There are better near nullspace vectors than the default, but
        # a constant should give a convergent solver, nonetheless.
        A = poisson((100,), format='csr')
        A = A + 1.0j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((A, None))
        A = poisson((10, 10), format='csr')
        A = A + 1.0j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((A, None))
Example #9
0
    def setUp(self):
        self.cases = []

        np.random.seed(2828777142)
        # Poisson problems in 1D and 2D
        N = 20
        self.cases.append((poisson(
            (2 * N, ), format='csr'), np.random.rand(2 * N, )))  # 0
        self.cases.append((poisson(
            (N, N), format='csr'), np.random.rand(N * N, )))  # 1
        # Boxed examples
        A = load_example('recirc_flow')['A'].tocsr()  # 2
        self.cases.append((A, np.random.rand(A.shape[0], )))
        A = load_example('bar')['A'].tobsr(blocksize=(3, 3))  # 3
        self.cases.append((A, np.random.rand(A.shape[0], )))
Example #10
0
    def setUp(self):
        self.cases = []

        A = poisson((5000,), format="csr")
        self.cases.append((A, None, 0.4, "symmetric", ("energy", {"krylov": "cg"})))
        self.cases.append((A, None, 0.4, "symmetric", ("energy", {"krylov": "gmres"})))

        A = poisson((75, 75), format="csr")
        self.cases.append((A, None, 0.26, "symmetric", ("energy", {"krylov": "cg"})))
        self.cases.append((A, None, 0.30, "symmetric", ("energy", {"krylov": "cgnr"})))

        A, B = linear_elasticity((50, 50), format="bsr")
        self.cases.append((A, B, 0.3, "symmetric", ("energy", {"krylov": "cg"})))
        self.cases.append((A, B, 0.3, "symmetric", ("energy", {"krylov": "cgnr"})))
        self.cases.append((A, B, 0.3, "symmetric", ("energy", {"krylov": "gmres"})))
Example #11
0
    def setUp(self):
        self.cases = []

        # Test 1
        A = poisson((5000, ), format='csr')
        Ai = A + 1.0j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((Ai, None, 0.12, 'symmetric', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((Ai, None, 0.12, 'symmetric', ('energy', {
            'krylov': 'gmres'
        })))

        # Test 2
        A = poisson((71, 71), format='csr')
        Ai = A + (0.625 / 0.01) * 1j * scipy.sparse.eye(A.shape[0], A.shape[1])
        self.cases.append((Ai, None, 1e-3, 'symmetric', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((Ai, None, 1e-3, 'symmetric', ('energy', {
            'krylov': 'cgnr'
        })))

        # Test 3
        A = poisson((60, 60), format='csr')
        Ai = 1.0j * A
        self.cases.append((Ai, None, 0.3, 'symmetric', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((Ai, None, 0.6, 'symmetric', ('energy', {
            'krylov': 'cgnr',
            'maxiter': 8
        })))
        self.cases.append((Ai, None, 0.6, 'symmetric', ('energy', {
            'krylov': 'gmres',
            'maxiter': 8
        })))

        # Test 4
        # Use an "inherently" imaginary problem, the Gauge Laplacian in 2D from
        # Quantum Chromodynamics,
        A = gauge_laplacian(70, spacing=1.0, beta=0.41)
        self.cases.append((A, None, 0.4, 'hermitian', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((A, None, 0.4, 'hermitian', ('energy', {
            'krylov': 'cg'
        })))
    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",
        ]
        rng = arange(1, n + 1, dtype="float").reshape(-1, 1)
        Bs = [ones((n, 1)), hstack((ones((n, 1)), rng))]

        for smoother in smoothers:
            for B in Bs:
                ml = smoothed_aggregation_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))
Example #13
0
    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 = smoothed_aggregation_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.25)
        assert (avg_convergence_ratio < 0.25)
Example #14
0
 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( (61,61),  format='csr'), ones((61*61,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 = smoothed_aggregation_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)
             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
Example #15
0
    def setUp(self):
        self.cases = []

        # Poisson problems in 2D
        for N in [2,3,5,7,8]:
            A = poisson( (N,N), format='csr'); A.data = A.data + 0.001j*rand(A.nnz)
            self.cases.append(A)
Example #16
0
    def test_solver_parameters(self):
        A = poisson((50, 50), format='csr')

        for method in methods:
            # method = ('richardson', {'omega':4.0/3.0})
            ml = smoothed_aggregation_solver(A,
                                             presmoother=method,
                                             postsmoother=method,
                                             max_coarse=10)

            residuals = profile_solver(ml)
            assert ((residuals[-1] / residuals[0])**(1.0 / len(residuals)) <
                    0.95)
            assert (ml.symmetric_smoothing)

        for method in methods2:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])

            residuals = profile_solver(ml)
            assert ((residuals[-1] / residuals[0])**(1.0 / len(residuals)) <
                    0.95)
            assert (not ml.symmetric_smoothing)

        for method in methods3:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])
            assert (ml.symmetric_smoothing)

        for method in methods4:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])
            assert (not ml.symmetric_smoothing)
Example #17
0
    def test_accel(self):
        from pyamg import smoothed_aggregation_solver
        from pyamg.krylov import cg, bicgstab

        A = poisson((50, 50), format='csr')
        b = rand(A.shape[0])

        ml = smoothed_aggregation_solver(A)

        # cg halts based on the preconditioner norm
        for accel in ['cg', cg]:
            x = ml.solve(b, maxiter=30, tol=1e-8, accel=accel)
            assert(precon_norm(b - A*x, ml) < 1e-8*precon_norm(b, ml))
            residuals = []
            x = ml.solve(b, maxiter=30, tol=1e-8, residuals=residuals,
                         accel=accel)
            assert(precon_norm(b - A*x, ml) < 1e-8*precon_norm(b, ml))
            # print residuals
            assert_almost_equal(precon_norm(b - A*x, ml), residuals[-1])

        # cgs and bicgstab use the Euclidean norm
        for accel in ['bicgstab', 'cgs', bicgstab]:
            x = ml.solve(b, maxiter=30, tol=1e-8, accel=accel)
            assert(norm(b - A*x) < 1e-8*norm(b))
            residuals = []
            x = ml.solve(b, maxiter=30, tol=1e-8, residuals=residuals,
                         accel=accel)
            assert(norm(b - A*x) < 1e-8*norm(b))
            # print residuals
            assert_almost_equal(norm(b - A*x), residuals[-1])
Example #18
0
    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']
        rng = np.arange(1, n + 1, dtype='float').reshape(-1, 1)
        Bs = [np.ones((n, 1)), sp.hstack((np.ones((n, 1)), rng))]

        # TODO:
        # why does python 3 require significant=6 while python 2 passes
        # why does python 3 yield a different dot() below than python 2
        # only for: ('gauss_seidel', {'sweep': 'symmetric'})
        for smoother in smoothers:
            for B in Bs:
                ml = smoothed_aggregation_solver(A, B, max_coarse=10,
                                                 presmoother=smoother,
                                                 postsmoother=smoother)
                P = ml.aspreconditioner()
                np.random.seed(0)
                x = sp.rand(n,)
                y = sp.rand(n,)
                out = (np.dot(P * x, y), np.dot(x, P * y))
                # print("smoother = %s %g %g" % (smoother, out[0], out[1]))
                assert_approx_equal(out[0], out[1])
Example #19
0
    def test_solver_parameters(self):
        A = poisson((50, 50), format='csr')

        for method in methods:
            #method = ('richardson', {'omega':4.0/3.0})
            ml = smoothed_aggregation_solver(A,
                                             presmoother=method,
                                             postsmoother=method,
                                             max_coarse=10)

            residuals = profile_solver(ml)
            #print "method",method
            #print "residuals",residuals
            #print "convergence rate:",(residuals[-1]/residuals[0])**(1.0/len(residuals))
            assert ((residuals[-1] / residuals[0])**(1.0 / len(residuals)) <
                    0.95)

        for method in methods2:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])

            residuals = profile_solver(ml)
            #print "method",method
            #print "residuals",residuals
            #print "convergence rate:",(residuals[-1]/residuals[0])**(1.0/len(residuals))
            assert ((residuals[-1] / residuals[0])**(1.0 / len(residuals)) <
                    0.95)
Example #20
0
    def test_poisson(self):
        cases = []

        cases.append((500,))
        cases.append((250, 250))
        cases.append((25, 25, 25))

        for case in cases:
            A = poisson(case, format='csr')

            np.random.seed(0)  # make tests repeatable

            x = sp.rand(A.shape[0])
            b = A*sp.rand(A.shape[0])  # zeros_like(x)

            ml = ruge_stuben_solver(A, max_coarse=50)

            res = []
            x_sol = ml.solve(b, x0=x, maxiter=20, tol=1e-12,
                             residuals=res)
            del x_sol

            avg_convergence_ratio = (res[-1]/res[0])**(1.0/len(res))

            assert(avg_convergence_ratio < 0.20)
Example #21
0
    def test_solver_parameters(self):
        A = poisson((50, 50), format='csr')

        for method in methods:
            # method = ('richardson', {'omega':4.0/3.0})
            ml = smoothed_aggregation_solver(A, presmoother=method,
                                             postsmoother=method,
                                             max_coarse=10)

            residuals = profile_solver(ml)
            assert((residuals[-1]/residuals[0])**(1.0/len(residuals)) < 0.95)
            assert(ml.symmetric_smoothing)

        for method in methods2:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])

            residuals = profile_solver(ml)
            assert((residuals[-1]/residuals[0])**(1.0/len(residuals)) < 0.95)
            assert(not ml.symmetric_smoothing)

        for method in methods3:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])
            assert(ml.symmetric_smoothing)

        for method in methods4:
            ml = smoothed_aggregation_solver(A, max_coarse=10)
            change_smoothers(ml, presmoother=method[0], postsmoother=method[1])
            assert(not ml.symmetric_smoothing)
    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 = smoothed_aggregation_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.25)
        assert avg_convergence_ratio < 0.25
Example #23
0
    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 = smoothed_aggregation_solver(A,
                                              coarse_solver=coarse1,
                                              max_coarse=500)
            sa2 = smoothed_aggregation_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_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']
        rng = np.arange(1, n + 1, dtype='float').reshape(-1, 1)
        Bs = [np.ones((n, 1)), np.hstack((np.ones((n, 1)), rng))]

        # TODO:
        # why does python 3 require significant=6 while python 2 passes
        # why does python 3 yield a different dot() below than python 2
        # only for: ('gauss_seidel', {'sweep': 'symmetric'})
        for smoother in smoothers:
            for B in Bs:
                ml = smoothed_aggregation_solver(A, B, max_coarse=10,
                                                 presmoother=smoother,
                                                 postsmoother=smoother)
                P = ml.aspreconditioner()
                np.random.seed(3849986793)
                x = np.random.rand(n,)
                y = np.random.rand(n,)
                out = (np.dot(P * x, y), np.dot(x, P * y))
                # print("smoother = %s %g %g" % (smoother, out[0], out[1]))
                assert_approx_equal(out[0], out[1])
Example #25
0
    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)
Example #26
0
    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))
Example #27
0
    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))
Example #28
0
    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))
Example #29
0
    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))
Example #30
0
    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
Example #31
0
    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())
Example #32
0
    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())
Example #33
0
    def setUp(self):
        self.cases = []

        # random matrices
        np.random.seed(0)
        for N in [2, 3, 5]:
            self.cases.append(csr_matrix(np.random.rand(N, N)))

        # Poisson problems in 1D and 2D
        for N in [2, 3, 5, 7, 10, 11, 19]:
            self.cases.append(poisson((N,), format='csr'))
        for N in [2, 3, 5, 7, 8]:
            self.cases.append(poisson((N, N), format='csr'))

        for name in ['knot', 'airfoil', 'bar']:
            ex = load_example(name)
            self.cases.append(ex['A'].tocsr())
Example #34
0
    def setUp(self):
        self.cases = []

        # random matrices
        np.random.seed(0)
        for N in [2, 3, 5]:
            self.cases.append(csr_matrix(rand(N, N)))

        # Poisson problems in 1D and 2D
        for N in [2, 3, 5, 7, 10, 11, 19]:
            self.cases.append(poisson((N, ), format='csr'))
        for N in [2, 3, 7, 9]:
            self.cases.append(poisson((N, N), format='csr'))

        for name in ['knot', 'airfoil', 'bar']:
            ex = load_example(name)
            self.cases.append(ex['A'].tocsr())
    def setUp(self):
        self.cases = []

        A = poisson((5000,), format="csr")
        self.cases.append((A, None, 0.4, "symmetric", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((A, None, 0.4, "symmetric", ("energy", {"krylov": "cg"})))
        self.cases.append((A, None, 0.5, "symmetric", ("energy", {"krylov": "gmres"})))

        A = poisson((60, 60), format="csr")
        self.cases.append((A, None, 0.42, "symmetric", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((A, None, 0.42, "symmetric", ("energy", {"krylov": "cg"})))
        self.cases.append((A, None, 0.42, "symmetric", ("energy", {"krylov": "cgnr"})))

        A, B = linear_elasticity((50, 50), format="bsr")
        self.cases.append((A, B, 0.32, "symmetric", ("jacobi", {"omega": 4.0 / 3.0})))
        self.cases.append((A, B, 0.22, "symmetric", ("energy", {"krylov": "cg"})))
        self.cases.append((A, B, 0.42, "symmetric", ("energy", {"krylov": "cgnr"})))
        self.cases.append((A, B, 0.42, "symmetric", ("energy", {"krylov": "gmres"})))
Example #36
0
    def setUp(self):
        self.cases = []

        # random matrices
        numpy.random.seed(0)
        for N in [2,3,5]:
            self.cases.append( csr_matrix(rand(N,N)) + csr_matrix(1.0j*rand(N,N)))

        # Poisson problems in 1D and 2D
        for N in [2,3,5,7,10,11,19]:
            A = poisson( (N,), format='csr'); A.data = A.data + 1.0j*A.data;
            self.cases.append(A)
        for N in [2,3,7,9]:
            A = poisson( (N,N), format='csr'); A.data = A.data + 1.0j*rand(A.data.shape[0],);
            self.cases.append(A)

        for name in ['knot','airfoil','bar']:
            ex = load_example(name)
            A = ex['A'].tocsr(); A.data = A.data + 0.5j*rand(A.data.shape[0],);
            self.cases.append(A)
    def test_precision(self):
        """Check single precision.

        Test that x_32 == x_64 up to single precision tolerance
        """
        np.random.seed(3158637515)  # make tests repeatable
        A = poisson((10, 10), dtype=np.float64, format='csr')
        b = np.random.rand(A.shape[0]).astype(A.dtype)
        ml = smoothed_aggregation_solver(A)
        x = np.random.rand(A.shape[0]).astype(A.dtype)
        x32 = ml.solve(b, x0=x, maxiter=1)

        np.random.seed(3158637515)  # make tests repeatable
        A = poisson((10, 10), dtype=np.float32, format='csr')
        b = np.random.rand(A.shape[0]).astype(A.dtype)
        ml = smoothed_aggregation_solver(A)
        x = np.random.rand(A.shape[0]).astype(A.dtype)
        x64 = ml.solve(b, x0=x, maxiter=1)

        assert_array_almost_equal(x32, x64, decimal=5)
Example #38
0
    def setUp(self):
        self.cases = []

        # Poisson problems in 1D and 2D
        for N in [10, 11, 19, 26]:
            A = poisson((N,), format='csr')
            tempAgg = standard_aggregation(A)
            T, B = fit_candidates(tempAgg, np.ones((A.shape[0],)) )
            self.cases.append( {'A': A, 'T': T, 'B': B} )
        for N in [5, 7, 9]:
            A = poisson((N,N), format='csr')
            tempAgg = standard_aggregation(A)
            T, B = fit_candidates(tempAgg, np.ones((A.shape[0],)) )
            self.cases.append( {'A': A, 'T': T, 'B': B} )

        for name in ['knot', 'airfoil', 'bar']:
            A = ex['A'].tocsr()
            tempAgg = standard_aggregation(A)
            T, B = fit_candidates(tempAgg, np.ones((A.shape[0],)) )
            self.cases.append( {'A': A, 'T': T, 'B': B} )
Example #39
0
    def setUp(self):
        self.cases = []

        # Poisson problems in 1D and 2D
        for N in [10, 11, 19, 26]:
            A = poisson((N, ), format='csr')
            tempAgg = standard_aggregation(A)
            T, B = fit_candidates(tempAgg, np.ones((A.shape[0], )))
            self.cases.append({'A': A, 'T': T, 'B': B})
        for N in [5, 7, 9]:
            A = poisson((N, N), format='csr')
            tempAgg = standard_aggregation(A)
            T, B = fit_candidates(tempAgg, np.ones((A.shape[0], )))
            self.cases.append({'A': A, 'T': T, 'B': B})

        for name in ['knot', 'airfoil', 'bar']:
            A = ex['A'].tocsr()
            tempAgg = standard_aggregation(A)
            T, B = fit_candidates(tempAgg, np.ones((A.shape[0], )))
            self.cases.append({'A': A, 'T': T, 'B': B})
Example #40
0
    def setUp(self):
        self.cases = []

        #

        # Random matrices, cases 0-2
        np.random.seed(0)
        for N in [2, 3, 5]:
            self.cases.append(csr_matrix(np.random.rand(N, N)))

        # Poisson problems in 1D, cases 3-9
        for N in [2, 3, 5, 7, 10, 11, 19]:
            self.cases.append(poisson((N,), format="csr"))

        # Poisson problems in 2D, cases 10-15
        for N in [2, 3, 5, 7, 10, 11]:
            self.cases.append(poisson((N, N), format="csr"))

        for name in ["knot", "airfoil", "bar"]:
            ex = load_example(name)
            self.cases.append(ex["A"].tocsr())
Example #41
0
    def setUp(self):
        cases = []
        np.random.seed(651978631)

        for i in range(5):
            A = np.random.rand(8, 8) > 0.5
            cases.append(canonical_graph(A + A.T).astype(float))

        cases.append(np.zeros((1, 1)))
        cases.append(np.zeros((2, 2)))
        cases.append(np.zeros((8, 8)))
        cases.append(np.ones((2, 2)) - np.eye(2))
        cases.append(poisson((5, )))
        cases.append(poisson((5, 5)))
        cases.append(poisson((11, 11)))
        cases.append(poisson((5, 5, 5)))
        for name in ['airfoil', 'bar', 'knot']:
            cases.append(load_example(name)['A'])

        cases = [canonical_graph(G) for G in cases]

        self.cases = cases
Example #42
0
    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
Example #43
0
    def setUp(self):
        cases = []
        seed(0)

        for i in range(5):
            A = rand(8, 8) > 0.5
            cases.append(canonical_graph(A + A.T).astype(float))

        cases.append(zeros((1, 1)))
        cases.append(zeros((2, 2)))
        cases.append(zeros((8, 8)))
        cases.append(ones((2, 2)) - eye(2))
        cases.append(poisson((5,)))
        cases.append(poisson((5, 5)))
        cases.append(poisson((11, 11)))
        cases.append(poisson((5, 5, 5)))
        for name in ['airfoil', 'bar', 'knot']:
            cases.append(load_example(name)['A'])

        cases = [canonical_graph(G) for G in cases]

        self.cases = cases
Example #44
0
    def setUp(self):
        self.cases = []

        A = poisson((5000,), format='csr')
        self.cases.append((A, None, 0.4, 'symmetric',
                          ('energy', {'krylov': 'cg'})))
        self.cases.append((A, None, 0.4, 'symmetric',
                          ('energy', {'krylov': 'gmres'})))

        A = poisson((75, 75), format='csr')
        self.cases.append((A, None, 0.26, 'symmetric',
                          ('energy', {'krylov': 'cg'})))
        self.cases.append((A, None, 0.30, 'symmetric',
                          ('energy', {'krylov': 'cgnr'})))

        A, B = linear_elasticity((50, 50), format='bsr')
        self.cases.append((A, B, 0.3, 'symmetric',
                          ('energy', {'krylov': 'cg'})))
        self.cases.append((A, B, 0.3, 'symmetric',
                          ('energy', {'krylov': 'cgnr'})))
        self.cases.append((A, B, 0.3, 'symmetric',
                          ('energy', {'krylov': 'gmres'})))
Example #45
0
    def setUp(self):
        self.cases = []

        A = poisson((5000,), format='csr')
        self.cases.append((A, None, 0.4, 'symmetric',
                          ('energy', {'krylov': 'cg'})))
        self.cases.append((A, None, 0.4, 'symmetric',
                          ('energy', {'krylov': 'gmres'})))

        A = poisson((75, 75), format='csr')
        self.cases.append((A, None, 0.26, 'symmetric',
                          ('energy', {'krylov': 'cg'})))
        self.cases.append((A, None, 0.30, 'symmetric',
                          ('energy', {'krylov': 'cgnr'})))

        A, B = linear_elasticity((50, 50), format='bsr')
        self.cases.append((A, B, 0.3, 'symmetric',
                          ('energy', {'krylov': 'cg'})))
        self.cases.append((A, B, 0.3, 'symmetric',
                          ('energy', {'krylov': 'cgnr'})))
        self.cases.append((A, B, 0.3, 'symmetric',
                          ('energy', {'krylov': 'gmres'})))
Example #46
0
    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.toarray())

        rs_old = ruge_stuben_solver(A, max_coarse=10)
        for AA in cases:
            rs_new = ruge_stuben_solver(AA, max_coarse=10)
            assert(np.abs(np.ravel(rs_old.levels[-1].A.toarray() - rs_new.levels[-1].A.toarray())).max() < 0.01)
            rs_old = rs_new
Example #47
0
def demo():
    """Outline basic demo."""
    A = poisson((100, 100), format='csr')  # 2D FD Poisson problem
    B = None  # no near-null spaces guesses for SA
    b = sp.rand(A.shape[0], 1)  # a random right-hand side

    # use AMG based on Smoothed Aggregation (SA) and display info
    mls = smoothed_aggregation_solver(A, B=B)
    print(mls)

    # Solve Ax=b with no acceleration ('standalone' solver)
    standalone_residuals = []
    x = mls.solve(b, tol=1e-10, accel=None, residuals=standalone_residuals)

    # Solve Ax=b with Conjugate Gradient (AMG as a preconditioner to CG)
    accelerated_residuals = []
    x = mls.solve(b, tol=1e-10, accel='cg', residuals=accelerated_residuals)
    del x

    # Compute relative residuals
    standalone_residuals = \
        np.array(standalone_residuals) / standalone_residuals[0]
    accelerated_residuals = \
        np.array(accelerated_residuals) / accelerated_residuals[0]

    # Compute (geometric) convergence factors
    factor1 = standalone_residuals[-1]**(1.0 / len(standalone_residuals))
    factor2 = accelerated_residuals[-1]**(1.0 / len(accelerated_residuals))

    print("                     MG convergence factor: %g" % (factor1))
    print("MG with CG acceleration convergence factor: %g" % (factor2))

    # Plot convergence history
    try:
        import matplotlib.pyplot as plt
        plt.figure()
        plt.title('Convergence History')
        plt.xlabel('Iteration')
        plt.ylabel('Relative Residual')
        plt.semilogy(standalone_residuals,
                     label='Standalone',
                     linestyle='-',
                     marker='o')
        plt.semilogy(accelerated_residuals,
                     label='Accelerated',
                     linestyle='-',
                     marker='s')
        plt.legend()
        plt.show()
    except ImportError:
        print("\n\nNote: pylab not available on your system.")
Example #48
0
    def setUp(self):
        self.cases = []

        A = poisson((5000, ), format='csr')
        self.cases.append((A, None, 0.4, 'symmetric', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((A, None, 0.4, 'symmetric', ('energy', {
            'krylov': 'cg'
        })))
        self.cases.append((A, None, 0.5, 'symmetric', ('energy', {
            'krylov': 'gmres'
        })))

        A = poisson((60, 60), format='csr')
        self.cases.append((A, None, 0.42, 'symmetric', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((A, None, 0.42, 'symmetric', ('energy', {
            'krylov': 'cg'
        })))
        self.cases.append((A, None, 0.42, 'symmetric', ('energy', {
            'krylov': 'cgnr'
        })))

        A, B = linear_elasticity((50, 50), format='bsr')
        self.cases.append((A, B, 0.32, 'symmetric', ('jacobi', {
            'omega': 4.0 / 3.0
        })))
        self.cases.append((A, B, 0.22, 'symmetric', ('energy', {
            'krylov': 'cg'
        })))
        self.cases.append((A, B, 0.42, 'symmetric', ('energy', {
            'krylov': 'cgnr'
        })))
        self.cases.append((A, B, 0.42, 'symmetric', ('energy', {
            'krylov': 'gmres'
        })))
Example #49
0
    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
Example #50
0
    def test_matrix_formats(self):
        warnings.simplefilter('ignore', SparseEfficiencyWarning)

        # 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.toarray())

        sa_old = smoothed_aggregation_solver(A, max_coarse=10)
        for AA in cases:
            sa_new = smoothed_aggregation_solver(AA, max_coarse=10)
            assert(np.abs(np.ravel(sa_old.levels[-1].A.toarray() - sa_new.levels[-1].A.toarray())).max() < 0.01)
            sa_old = sa_new
Example #51
0
    def setUp(self):
        self.cases = []

        # random matrices
        np.random.seed(0)
        for N in [2, 3, 5]:
            self.cases.append(
                csr_matrix(rand(N, N)) + csr_matrix(1.0j * rand(N, N)))

        # Poisson problems in 1D and 2D
        for N in [2, 3, 5, 7, 10, 11, 19]:
            A = poisson((N, ), format='csr')
            A.data = A.data + 1.0j * A.data
            self.cases.append(A)
        for N in [2, 3, 7, 9]:
            A = poisson((N, N), format='csr')
            A.data = A.data + 1.0j * rand(A.data.shape[0], )
            self.cases.append(A)

        for name in ['knot', 'airfoil', 'bar']:
            ex = load_example(name)
            A = ex['A'].tocsr()
            A.data = A.data + 0.5j * rand(A.data.shape[0], )
            self.cases.append(A)
Example #52
0
    def test_coarse_grid_solver(self):
        cases = []

        cases.append(csr_matrix(diag(arange(1, 5))))
        cases.append(poisson((4, ), format='csr'))
        cases.append(poisson((4, 4), format='csr'))

        # Make cases complex
        cases = [G + 1e-5j * G for G in cases]
        cases = [0.5 * (G + G.H) for G in cases]

        # method should be almost exact for small matrices
        for A in cases:
            for solver in ['splu', 'pinv', 'pinv2', 'lu', 'cholesky', 'cg']:
                s = coarse_grid_solver(solver)

                b = arange(A.shape[0], dtype=A.dtype)

                x = s(A, b)
                assert_almost_equal(A * x, b)

                # subsequent calls use cached data
                x = s(A, b)
                assert_almost_equal(A * x, b)
Example #53
0
    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((61, 61), format='csr'), np.ones(
            (61 * 61, 1)), 0.9))
        cases.append((A_elas, B_elas, 0.9))
        for (A, B, rho_scale) in cases:
            last_rho = -1.0
            x0 = sp.rand(A.shape[0], 1)
            b = sp.rand(A.shape[0], 1)
            for ic in improve_candidates_list:
                ml = smoothed_aggregation_solver(A,
                                                 B,
                                                 max_coarse=10,
                                                 improve_candidates=ic)
                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
Example #54
0
    def topyamg(self):
        r""" Create a `pyamg` stencil matrix to be used in pyamg

        This allows retrieving the grid matrix equivalent of the real-space grid.
        Subsequently the returned matrix may be used in pyamg for solutions etc.

        The `pyamg` suite is it-self a rather complicated code with many options.
        For details we refer to `pyamg <pyamg https://github.com/pyamg/pyamg/>`_.

        Returns
        -------
        A : scipy.sparse.csr_matrix which contains the grid stencil for a `pyamg` solver.
        b : numpy.ndarray containing RHS of the linear system of equations.

        Examples
        --------
        This example proves the best method for a variety of cases in regards of the 3D Poisson problem:

        >>> grid = Grid(0.01)
        >>> A, b = grid.topyamg() # automatically setups the current boundary conditions
        >>> # add terms etc. to A and/or b
        >>> import pyamg
        >>> from scipy.sparse.linalg import cg
        >>> ml = pyamg.aggregation.smoothed_aggregation_solver(A, max_levels=1000)
        >>> M = ml.aspreconditioner(cycle='W') # pre-conditioner
        >>> x, info = cg(A, b, tol=1e-12, M=M)

        See Also
        --------
        pyamg_index : convert grid indices into the sparse matrix indices for ``A``
        pyamg_fix : fixes stencil for indices and fixes the source for the RHS matrix (uses `pyamg_source`)
        pyamg_source : fix the RHS matrix ``b`` to a constant value
        pyamg_boundary_condition : setup the sparse matrix ``A`` to given boundary conditions (called in this routine)
        """
        from pyamg.gallery import poisson
        # Initially create the CSR matrix
        A = poisson(self.shape, dtype=self.dtype, format='csr')
        b = np.zeros(A.shape[0], dtype=A.dtype)

        # Now apply the boundary conditions
        self.pyamg_boundary_condition(A, b)
        return A, b
Example #55
0
    def test_matrix_formats(self):
        warnings.filterwarnings('ignore', category=SparseEfficiencyWarning)

        # 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.toarray())

        np.random.seed(111908910)
        sa_old = adaptive_sa_solver(A, initial_candidates=np.ones((49, 1)),
                                    max_coarse=10)[0]
        for AA in cases:
            np.random.seed(111908910)
            sa_new = adaptive_sa_solver(AA,
                                        initial_candidates=np.ones((49, 1)),
                                        max_coarse=10)[0]
            assert(abs(np.ravel(sa_old.levels[-1].A.toarray()
                   - sa_new.levels[-1].A.toarray())).max() < 0.01)
            sa_old = sa_new
Example #56
0
    def test_poisson(self):
        cases = []

        # perturbed Laplacian
        A = poisson((50, 50), format='csr')
        Ai = A.copy()
        Ai.data = Ai.data + 1e-5j * np.random.rand(Ai.nnz)
        cases.append((Ai, 0.25))

        # imaginary Laplacian
        Ai = 1.0j * A
        cases.append((Ai, 0.25))

        # JBS:  Not sure if this is a valid test case
        # imaginary shift
        # Ai = A + 1.1j*sparse.eye(A.shape[0], A.shape[1])
        # cases.append((Ai,0.8))

        for A, rratio in cases:
            [asa, work] = adaptive_sa_solver(A,
                                             num_candidates=1,
                                             symmetry='symmetric')
            # sa = smoothed_aggregation_solver(A, B = np.ones((A.shape[0],1)) )

            b = np.zeros((A.shape[0], ))
            x0 = (np.random.rand(A.shape[0], ) +
                  1.0j * np.random.rand(A.shape[0], ))

            residuals0 = []

            sol0 = asa.solve(b,
                             x0=x0,
                             maxiter=20,
                             tol=1e-10,
                             residuals=residuals0)
            del sol0

            conv_asa = \
                (residuals0[-1] / residuals0[0]) ** (1.0 / len(residuals0))

            assert (conv_asa < rratio)
Example #57
0
    def test_poisson(self):
        A = poisson((50, 50), format='csr')

        [asa, work] = adaptive_sa_solver(A, num_candidates=1)
        sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0], 1)))

        b = sp.rand(A.shape[0])

        residuals0 = []
        residuals1 = []

        sol0 = asa.solve(b, maxiter=20, tol=1e-10, residuals=residuals0)
        sol1 = sa.solve(b, maxiter=20, tol=1e-10, residuals=residuals1)
        del sol0, sol1

        conv_asa = (residuals0[-1] / residuals0[0])**(1.0 / len(residuals0))
        conv_sa = (residuals1[-1] / residuals1[0])**(1.0 / len(residuals1))

        # print "ASA convergence (Poisson)",conv_asa
        # print "SA convergence (Poisson)",conv_sa
        assert (conv_asa < 1.2 * conv_sa)
Example #58
0
    def test_aspreconditioner(self):
        from pyamg import smoothed_aggregation_solver
        from scipy.sparse.linalg import cg
        from pyamg.krylov import fgmres

        A = poisson((50, 50), format='csr')
        b = rand(A.shape[0])

        ml = smoothed_aggregation_solver(A)

        for cycle in ['V', 'W', 'F']:
            M = ml.aspreconditioner(cycle=cycle)
            x, info = cg(A, b, tol=1e-8, maxiter=30, M=M)
            # cg satisfies convergence in the preconditioner norm
            assert (precon_norm(b - A * x, ml) < 1e-8 * precon_norm(b, ml))

        for cycle in ['AMLI']:
            M = ml.aspreconditioner(cycle=cycle)
            x, info = fgmres(A, b, tol=1e-8, maxiter=30, M=M)
            # fgmres satisfies convergence in the 2-norm
            assert (norm(b - A * x) < 1e-8 * norm(b))