Ejemplo n.º 1
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))
Ejemplo n.º 2
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))
Ejemplo n.º 3
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())
Ejemplo n.º 4
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())
Ejemplo n.º 5
0
    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())
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
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
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
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)))
        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
Ejemplo n.º 11
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))
Ejemplo n.º 12
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))
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
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 = 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)
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
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 = 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)
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
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((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
Ejemplo n.º 20
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))
Ejemplo n.º 21
0
    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())
Ejemplo n.º 22
0
    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,
Ejemplo n.º 23
0
    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())