コード例 #1
0
    def test_prefilter(self):
        """Check that using prefilter reduces NNZ in P"""
        np.random.seed(0)  # make tests repeatable
        cases = []

        # Simple, real-valued diffusion problems
        X = load_example('airfoil')
        A = X['A'].tocsr()
        B = X['B']

        cases.append((A, B,
                      ('energy', {'krylov': 'cg', 'degree': 2, 'maxiter': 3}),
                      {'theta': 0.05}))

        cases.append((A, B,
                      ('energy', {'krylov': 'gmres', 'degree': 2,
                                  'maxiter': 3}),
                      {'k': 3}))

        cases.append((A.tobsr(blocksize=(2, 2)),
                      np.hstack((B, np.random.rand(B.shape[0], 1))),
                      ('energy', {'krylov': 'cg', 'degree': 2,
                                  'maxiter': 3}),
                      {'theta': 0.1}))

        # Simple, imaginary-valued problems
        iA = 1.0j * A
        iB = 1.0 + np.random.rand(iA.shape[0], 2)\
                 + 1.0j * (1.0 + np.random.rand(iA.shape[0], 2))

        cases.append((iA, B,
                      ('energy', {'krylov': 'cg', 'degree': 2, 'maxiter': 3}),
                      {'theta': 0.05}))

        cases.append((iA, iB,
                      ('energy', {'krylov': 'gmres', 'degree': 2,
                                  'maxiter': 3}),
                      {'k': 3}))

        cases.append((A.tobsr(blocksize=(2, 2)),
                      np.hstack((B, np.random.rand(B.shape[0], 1))),
                      ('energy', {'krylov': 'cg', 'degree': 2, 'maxiter': 3}),
                      {'theta': 0.1}))

        for A, B, smooth, prefilter in cases:
            ml_nofilter = rootnode_solver(A, B=B, max_coarse=1, max_levels=2,
                                          smooth=smooth, keep=True)
            smooth[1]['prefilter'] = prefilter
            ml_filter = rootnode_solver(A, B=B, max_coarse=1, max_levels=2,
                                        smooth=smooth, keep=True)
            assert_equal(ml_nofilter.levels[0].P.nnz >
                         ml_filter.levels[0].P.nnz, True)
コード例 #2
0
ファイル: test_smooth.py プロジェクト: pyamg/pyamg
    def test_prefilter(self):
        """Check that using prefilter reduces NNZ in P"""
        np.random.seed(0)  # make tests repeatable
        cases = []

        # Simple, real-valued diffusion problems
        X = load_example('airfoil')
        A = X['A'].tocsr()
        B = X['B']

        cases.append((A, B,
                      ('energy', {'krylov': 'cg', 'degree': 2, 'maxiter': 3}),
                      {'theta': 0.05}))

        cases.append((A, B,
                      ('energy', {'krylov': 'gmres', 'degree': 2,
                                  'maxiter': 3}),
                      {'k': 3}))

        cases.append((A.tobsr(blocksize=(2, 2)),
                      np.hstack((B, np.random.rand(B.shape[0], 1))),
                      ('energy', {'krylov': 'cg', 'degree': 2,
                                  'maxiter': 3}),
                      {'theta': 0.1}))

        # Simple, imaginary-valued problems
        iA = 1.0j * A
        iB = 1.0 + np.random.rand(iA.shape[0], 2)\
                 + 1.0j * (1.0 + np.random.rand(iA.shape[0], 2))

        cases.append((iA, B,
                      ('energy', {'krylov': 'cg', 'degree': 2, 'maxiter': 3}),
                      {'theta': 0.05}))

        cases.append((iA, iB,
                      ('energy', {'krylov': 'gmres', 'degree': 2,
                                  'maxiter': 3}),
                      {'k': 3}))

        cases.append((A.tobsr(blocksize=(2, 2)),
                      np.hstack((B, np.random.rand(B.shape[0], 1))),
                      ('energy', {'krylov': 'cg', 'degree': 2, 'maxiter': 3}),
                      {'theta': 0.1}))

        for A, B, smooth, prefilter in cases:
            ml_nofilter = rootnode_solver(A, B=B, max_coarse=1, max_levels=2,
                                          smooth=smooth, keep=True)
            smooth[1]['prefilter'] = prefilter
            ml_filter = rootnode_solver(A, B=B, max_coarse=1, max_levels=2,
                                        smooth=smooth, keep=True)
            assert_equal(ml_nofilter.levels[0].P.nnz >
                         ml_filter.levels[0].P.nnz, True)
コード例 #3
0
ファイル: test_smooth.py プロジェクト: pyamg/pyamg
    def test_prefilter(self):
        """Check that using prefilter reduces NNZ in P"""
        np.random.seed(0)  # make tests repeatable
        cases = []

        # Simple, real-valued diffusion problems
        X = load_example("airfoil")
        A = X["A"].tocsr()
        B = X["B"]

        cases.append((A, B, ("energy", {"krylov": "cg", "degree": 2, "maxiter": 3}), {"theta": 0.05}))

        cases.append((A, B, ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3}), {"k": 3}))

        cases.append(
            (
                A.tobsr(blocksize=(2, 2)),
                np.hstack((B, np.random.rand(B.shape[0], 1))),
                ("energy", {"krylov": "cg", "degree": 2, "maxiter": 3}),
                {"theta": 0.1},
            )
        )

        # Simple, imaginary-valued problems
        iA = 1.0j * A
        iB = 1.0 + np.random.rand(iA.shape[0], 2) + 1.0j * (1.0 + np.random.rand(iA.shape[0], 2))

        cases.append((iA, B, ("energy", {"krylov": "cg", "degree": 2, "maxiter": 3}), {"theta": 0.05}))

        cases.append((iA, iB, ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3}), {"k": 3}))

        cases.append(
            (
                A.tobsr(blocksize=(2, 2)),
                np.hstack((B, np.random.rand(B.shape[0], 1))),
                ("energy", {"krylov": "cg", "degree": 2, "maxiter": 3}),
                {"theta": 0.1},
            )
        )

        for A, B, smooth, prefilter in cases:
            ml_nofilter = rootnode_solver(A, B=B, max_coarse=1, max_levels=2, smooth=smooth, keep=True)
            smooth[1]["prefilter"] = prefilter
            ml_filter = rootnode_solver(A, B=B, max_coarse=1, max_levels=2, smooth=smooth, keep=True)
            assert_equal(ml_nofilter.levels[0].P.nnz > ml_filter.levels[0].P.nnz, True)
コード例 #4
0
    def test_range(self):
        """Check that P*R=B"""
        numpy.random.seed(0) #make tests repeatable
        
        cases = []

        ##
        # Simple, real-valued diffusion problems
        X = load_example('airfoil')
        A = X['A'].tocsr(); B = X['B']
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'local'}) ))
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'block'}) ))

        cases.append((A,B,('energy', {'maxiter' : 3}) ))
        cases.append((A,B,('energy', {'krylov' : 'cgnr'}) ))
        cases.append((A,B,('energy', {'krylov' : 'gmres', 'degree' : 2}) ))
        
        A = poisson((10,10), format='csr')
        B = ones((A.shape[0],1))
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'diagonal'}) ))
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'local'}) ))

        cases.append((A,B,'energy'))
        cases.append((A,B,('energy', {'degree' : 2}) ))
        cases.append((A,B,('energy', {'krylov' : 'cgnr', 'degree' : 2}) ))
        cases.append((A,B,('energy', {'krylov' : 'gmres'}) ))

        ##
        # Simple, imaginary-valued problems
        iA = 1.0j*A
        iB = 1.0 + rand(iA.shape[0],2) + 1.0j*(1.0 + rand(iA.shape[0],2))
        
        cases.append((iA, B,('jacobi', {'filter' : True, 'weighting' : 'diagonal'}) ))
        cases.append((iA, B,('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        cases.append((iA,iB,('jacobi', {'filter' : True, 'weighting' : 'local'}) ))
        cases.append((iA,iB,('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        
        cases.append((iA.tobsr(blocksize=(5,5)),  B, ('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        cases.append((iA.tobsr(blocksize=(5,5)), iB, ('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        
        cases.append((iA,B, ('energy', {'krylov' : 'cgnr', 'degree' : 2}) ))
        cases.append((iA,iB,('energy', {'krylov' : 'cgnr'}) ))
        cases.append((iA.tobsr(blocksize=(5,5)),B, ('energy', {'krylov' : 'cgnr', 'degree' : 2, 'maxiter' : 3}) ))
        cases.append((iA.tobsr(blocksize=(5,5)),iB,('energy', {'krylov' : 'cgnr'}) ))
 
        cases.append((iA,B, ('energy', {'krylov' : 'gmres'}) ))
        cases.append((iA,iB,('energy', {'krylov' : 'gmres', 'degree' : 2}) ))
        cases.append((iA.tobsr(blocksize=(5,5)),B, ('energy', {'krylov' : 'gmres', 'degree' : 2, 'maxiter' : 3}) ))
        cases.append((iA.tobsr(blocksize=(5,5)),iB,('energy', {'krylov' : 'gmres'}) ))

        ##
        #
        # Simple, imaginary-valued problems
        iA = A + 1.0j*scipy.sparse.eye(A.shape[0], A.shape[1])

        cases.append((iA,B, ('jacobi', {'filter' : True, 'weighting' : 'local'}) ))
        cases.append((iA,B, ('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        cases.append((iA,iB,('jacobi', {'filter' : True, 'weighting' : 'diagonal'}) ))
        cases.append((iA,iB,('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        cases.append((iA.tobsr(blocksize=(4,4)), iB, ('jacobi', {'filter' : True, 'weighting' : 'block'}) ))
        
        cases.append((iA,B,  ('energy', {'krylov' : 'cgnr'}) ))
        cases.append((iA.tobsr(blocksize=(4,4)),iB,('energy', {'krylov' : 'cgnr'}) ))

        cases.append((iA,B,                         ('energy', {'krylov' : 'gmres'}) ))
        cases.append((iA.tobsr(blocksize=(4,4)),iB, ('energy', {'krylov' : 'gmres', 'degree' : 2, 'maxiter' : 3}) ))

        ##
        #
        A = gauge_laplacian(10, spacing=1.0, beta=0.21)
        B = ones((A.shape[0],1))
        cases.append((A,iB,('jacobi', {'filter' : True, 'weighting' : 'diagonal'}) ))
        cases.append((A,iB,('jacobi', {'filter' : True, 'weighting' : 'local'}) ))

        cases.append((A,B,                        ('energy', {'krylov' : 'cg'}) ))
        cases.append((A,iB,                       ('energy', {'krylov' : 'cgnr'}) ))
        cases.append((A,iB,                       ('energy', {'krylov' : 'gmres'}) ))
        
        cases.append((A.tobsr(blocksize=(2,2)),B, ('energy', {'krylov' : 'cgnr', 'degree' : 2, 'maxiter' : 3}) ))
        cases.append((A.tobsr(blocksize=(2,2)),iB,('energy', {'krylov' : 'cg'}) ))
        cases.append((A.tobsr(blocksize=(2,2)),B, ('energy', {'krylov' : 'gmres', 'degree' : 2, 'maxiter' : 3}) ))

        ##
        #
        A,B = linear_elasticity((10,10))
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'diagonal'}) ))
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'local'}) ))
        cases.append((A,B,('jacobi', {'filter' : True, 'weighting' : 'block'}) ))

        cases.append((A,B,('energy', {'degree' : 2}) ))
        cases.append((A,B,('energy', {'krylov' : 'cgnr'}) ))
        cases.append((A,B,('energy', {'krylov' : 'gmres', 'degree' : 2}) ))
               

        ##
        # Classic SA cases
        for A,B,smooth in cases:
            ml = smoothed_aggregation_solver(A, B=B, max_coarse=1, max_levels=2, smooth=smooth )
            P = ml.levels[0].P
            B = ml.levels[0].B
            R = ml.levels[1].B
            assert_almost_equal(P*R, B)
        
        def blocksize(A):
            # Helper Function: return the blocksize of a matrix 
            if isspmatrix_bsr(A):
                return A.blocksize[0]
            else:
                return 1

        ##
        # Root-node cases
        counter = 0
        for A,B,smooth in cases:
            counter += 1
            
            if isinstance( smooth, tuple):
                smoother = smooth[0]
            else:
                smoother = smooth
            
            if smoother == 'energy' and (B.shape[1] >= blocksize(A)):
                 ml = rootnode_solver(A, B=B, max_coarse=1, max_levels=2, smooth=smooth, 
                         improve_candidates =[('gauss_seidel_nr', {'sweep': 'symmetric', 'iterations': 4}), None],
                         keep=True, symmetry='nonsymmetric')
                 T = ml.levels[0].T.tocsr()
                 Cpts = ml.levels[0].Cpts
                 Bf = ml.levels[0].B 
                 Bf_H = ml.levels[0].BH 
                 Bc = ml.levels[1].B 
                 P = ml.levels[0].P.tocsr()
                 ##
                 # P should preserve B in its range, wherever P 
                 # has enough nonzeros
                 mask = ((P.indptr[1:] - P.indptr[:-1]) >= B.shape[1])
                 assert_almost_equal( (P*Bc)[mask,:], Bf[mask,:])
                 assert_almost_equal( (P*Bc)[mask,:], Bf_H[mask,:])
                 ##
                 # P should be the identity at Cpts
                 I = eye(T.shape[1], T.shape[1], format='csr', dtype=T.dtype)
                 I2 = P[Cpts,:]
                 assert_almost_equal(I.data, I2.data)
                 assert_equal(I.indptr, I2.indptr)
                 assert_equal(I.indices, I2.indices)
                 ##
                 # T should be the identity at Cpts
                 I2 = T[Cpts,:]
                 assert_almost_equal(I.data, I2.data)
                 assert_equal(I.indptr, I2.indptr)
                 assert_equal(I.indices, I2.indices)
コード例 #5
0
ファイル: test_smooth.py プロジェクト: Alexey-Voronin/pyamg-1
    def test_range(self):
        """Check that P*R=B."""
        warnings.filterwarnings('ignore', category=UserWarning,
                                message='Having less target vectors')
        np.random.seed(18410243)  # make tests repeatable

        cases = []

        # Simple, real-valued diffusion problems
        name = 'airfoil'
        X = load_example('airfoil')
        A = X['A'].tocsr()
        B = X['B']
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'local'}), name))
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'block'}), name))

        cases.append((A, B, ('energy', {'maxiter': 3}), name))
        cases.append((A, B, ('energy', {'krylov': 'cgnr', 'weighting': 'diagonal'}), name))
        cases.append((A, B, ('energy', {'krylov': 'gmres', 'degree': 2}), name))

        name = 'poisson'
        A = poisson((10, 10), format='csr')
        B = np.ones((A.shape[0], 1))
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'diagonal'}), name))
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'local'}), name))

        cases.append((A, B, 'energy', name))
        cases.append((A, B, ('energy', {'degree': 2}), name))
        cases.append((A, B, ('energy', {'krylov': 'cgnr', 'degree': 2,
                                        'weighting': 'diagonal'}), name))
        cases.append((A, B, ('energy', {'krylov': 'gmres'}), name))

        # Simple, imaginary-valued problems
        name = 'random imaginary'
        iA = 1.0j * A
        iB = 1.0 + np.random.rand(iA.shape[0], 2)\
                 + 1.0j * (1.0 + np.random.rand(iA.shape[0], 2))

        cases.append((iA, B, ('jacobi',
                              {'filter_entries': True, 'weighting': 'diagonal'}), name))
        cases.append((iA, B, ('jacobi',
                              {'filter_entries': True, 'weighting': 'block'}), name))
        cases.append((iA, iB, ('jacobi',
                               {'filter_entries': True, 'weighting': 'local'}), name))
        cases.append((iA, iB, ('jacobi',
                               {'filter_entries': True, 'weighting': 'block'}), name))

        cases.append((iA.tobsr(blocksize=(5, 5)), B,
                      ('jacobi', {'filter_entries': True, 'weighting': 'block'}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), iB,
                      ('jacobi', {'filter_entries': True, 'weighting': 'block'}), name))

        cases.append((iA, B, ('energy', {'krylov': 'cgnr', 'degree': 2,
                                         'weighting': 'diagonal'}), name))
        cases.append((iA, iB, ('energy', {'krylov': 'cgnr',
                                          'weighting': 'diagonal'}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), B,
                      ('energy',
                       {'krylov': 'cgnr', 'degree': 2, 'maxiter': 3,
                        'weighting': 'diagonal', 'postfilter': {'theta': 0.05}}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), B,
                      ('energy',
                       {'krylov': 'cgnr', 'degree': 2, 'maxiter': 3,
                        'weighting': 'diagonal',
                        'prefilter': {'theta': 0.05}}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), B,
                      ('energy',
                       {'krylov': 'cgnr', 'degree': 2,
                        'weighting': 'diagonal', 'maxiter': 3}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), iB,
                      ('energy', {'krylov': 'cgnr', 'weighting': 'diagonal'}), name))

        cases.append((iA, B, ('energy', {'krylov': 'gmres'}), name))
        cases.append((iA, iB, ('energy', {'krylov': 'gmres', 'degree': 2}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), B,
                      ('energy',
                       {'krylov': 'gmres', 'degree': 2, 'maxiter': 3}), name))
        cases.append((iA.tobsr(blocksize=(5, 5)), iB,
                      ('energy', {'krylov': 'gmres'}), name))

        # Simple, imaginary-valued problems
        name = 'random imaginary + I'
        iA = A + 1.0j * sparse.eye(A.shape[0], A.shape[1])

        cases.append((iA, B, ('jacobi',
                              {'filter_entries': True, 'weighting': 'local'}), name))
        cases.append((iA, B, ('jacobi',
                              {'filter_entries': True, 'weighting': 'block'}), name))
        cases.append((iA, iB, ('jacobi',
                               {'filter_entries': True, 'weighting': 'diagonal'}), name))
        cases.append((iA, iB, ('jacobi',
                               {'filter_entries': True, 'weighting': 'block'}), name))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB,
                      ('jacobi', {'filter_entries': True, 'weighting': 'block'}), name))

        cases.append((iA, B, ('energy', {'krylov': 'cgnr', 'weighting': 'diagonal'}), name))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB,
                      ('energy', {'krylov': 'cgnr', 'weighting': 'diagonal'}), name))

        cases.append((iA, B, ('energy', {'krylov': 'gmres'}), name))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB,
                      ('energy',
                       {'krylov': 'gmres', 'degree': 2, 'maxiter': 3}), name))

        cases.append((iA.tobsr(blocksize=(4, 4)), iB,
                      ('energy',
                       {'krylov': 'gmres', 'degree': 2, 'maxiter': 3,
                        'postfilter': {'theta': 0.05}}), name))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB,
                      ('energy',
                       {'krylov': 'gmres', 'degree': 2, 'maxiter': 3,
                        'prefilter': {'theta': 0.05}}), name))

        name = 'gauge laplacian'
        A = gauge_laplacian(10, spacing=1.0, beta=0.21)
        B = np.ones((A.shape[0], 1))
        cases.append((A, iB, ('jacobi',
                              {'filter_entries': True, 'weighting': 'diagonal'}), name))
        cases.append((A, iB, ('jacobi',
                              {'filter_entries': True, 'weighting': 'local'}), name))

        cases.append((A, B, ('energy', {'krylov': 'cg'}), name))
        cases.append((A, iB, ('energy', {'krylov': 'cgnr', 'weighting': 'diagonal'}), name))
        cases.append((A, iB, ('energy', {'krylov': 'gmres'}), name))

        name = 'gauge laplacian bsr'
        cases.append((A.tobsr(blocksize=(2, 2)), B,
                      ('energy', {'krylov': 'cgnr', 'degree': 2, 'weighting': 'diagonal',
                                  'maxiter': 3, 'postfilter': {'theta': 0.05}}),
                     name))
        cases.append((A.tobsr(blocksize=(2, 2)), B,
                      ('energy', {'krylov': 'cgnr', 'degree': 2, 'weighting': 'diagonal',
                       'maxiter': 3, 'prefilter': {'theta': 0.05}}),
                     name))
        cases.append((A.tobsr(blocksize=(2, 2)), B,
                      ('energy', {'krylov': 'cgnr', 'degree': 2, 'maxiter': 3,
                                  'weighting': 'diagonal'}),
                      name))
        cases.append((A.tobsr(blocksize=(2, 2)), iB,
                     ('energy', {'krylov': 'cg'}), name))
        cases.append((A.tobsr(blocksize=(2, 2)), B,
                      ('energy', {'krylov': 'gmres', 'degree': 2, 'maxiter': 3}),
                      name))
        cases.append((A.tobsr(blocksize=(2, 2)), B,
                     ('energy', {'krylov': 'gmres', 'degree': 2,
                      'maxiter': 3, 'postfilter': {'theta': 0.05}}),
                     name))
        cases.append((A.tobsr(blocksize=(2, 2)), B,
                     ('energy', {'krylov': 'gmres', 'degree': 2,
                      'maxiter': 3, 'prefilter': {'theta': 0.05}}),
                     name))

        #
        name = 'linear elasticity'
        A, B = linear_elasticity((10, 10))
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'diagonal'}), name))
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'local'}), name))
        cases.append((A, B, ('jacobi',
                             {'filter_entries': True, 'weighting': 'block'}), name))
        cases.append((A, B, ('energy', {'degree': 2}), name))
        cases.append((A, B, ('energy', {'degree': 3, 'postfilter': {'theta': 0.05}}), name))
        cases.append((A, B, ('energy', {'degree': 3, 'prefilter': {'theta': 0.05}}), name))
        cases.append((A, B, ('energy', {'krylov': 'cgnr', 'weighting': 'diagonal'}), name))
        cases.append((A, B, ('energy', {'krylov': 'gmres', 'degree': 2}), name))

        # Classic SA cases
        for A, B, smooth, _name in cases:
            ml = smoothed_aggregation_solver(A, B=B, max_coarse=1,
                                             max_levels=2, smooth=smooth)
            P = ml.levels[0].P
            B = ml.levels[0].B
            R = ml.levels[1].B
            assert_almost_equal(P * R, B)

        def _get_blocksize(A):
            # Helper Function: return the blocksize of a matrix
            if sparse.isspmatrix_bsr(A):
                return A.blocksize[0]

            return 1

        # Root-node cases
        counter = 0
        for A, B, smooth, _name in cases:
            counter += 1

            if isinstance(smooth, tuple):
                smoother = smooth[0]
            else:
                smoother = smooth

            if smoother == 'energy' and (B.shape[1] >= _get_blocksize(A)):
                ic = [('gauss_seidel_nr',
                       {'sweep': 'symmetric', 'iterations': 4}), None]
                ml = rootnode_solver(A, B=B, max_coarse=1, max_levels=2,
                                     smooth=smooth,
                                     improve_candidates=ic,
                                     keep=True, symmetry='nonsymmetric')
                T = ml.levels[0].T.tocsr()
                Cpts = ml.levels[0].Cpts
                Bf = ml.levels[0].B
                Bf_H = ml.levels[0].BH
                Bc = ml.levels[1].B
                P = ml.levels[0].P.tocsr()

                T.eliminate_zeros()
                P.eliminate_zeros()

                # P should preserve B in its range, wherever P
                # has enough nonzeros
                mask = ((P.indptr[1:] - P.indptr[:-1]) >= B.shape[1])
                assert_almost_equal((P*Bc)[mask, :], Bf[mask, :])
                assert_almost_equal((P*Bc)[mask, :], Bf_H[mask, :])

                # P should be the identity at Cpts
                I1 = sparse.eye(T.shape[1], T.shape[1], format='csr', dtype=T.dtype)
                I2 = P[Cpts, :]
                assert_almost_equal(I1.data, I2.data)
                assert_equal(I1.indptr, I2.indptr)
                assert_equal(I1.indices, I2.indices)

                # T should be the identity at Cpts
                I2 = T[Cpts, :]
                assert_almost_equal(I1.data, I2.data)
                assert_equal(I1.indptr, I2.indptr)
                assert_equal(I1.indices, I2.indices)
コード例 #6
0
ファイル: test_smooth.py プロジェクト: pyamg/pyamg
    def test_range(self):
        """Check that P*R=B"""
        np.random.seed(0)  # make tests repeatable

        cases = []

        # Simple, real-valued diffusion problems
        X = load_example("airfoil")
        A = X["A"].tocsr()
        B = X["B"]
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "local"})))
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "block"})))

        cases.append((A, B, ("energy", {"maxiter": 3})))
        cases.append((A, B, ("energy", {"krylov": "cgnr"})))
        cases.append((A, B, ("energy", {"krylov": "gmres", "degree": 2})))

        A = poisson((10, 10), format="csr")
        B = np.ones((A.shape[0], 1))
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "diagonal"})))
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "local"})))

        cases.append((A, B, "energy"))
        cases.append((A, B, ("energy", {"degree": 2})))
        cases.append((A, B, ("energy", {"krylov": "cgnr", "degree": 2})))
        cases.append((A, B, ("energy", {"krylov": "gmres"})))

        # Simple, imaginary-valued problems
        iA = 1.0j * A
        iB = 1.0 + np.random.rand(iA.shape[0], 2) + 1.0j * (1.0 + np.random.rand(iA.shape[0], 2))

        cases.append((iA, B, ("jacobi", {"filter": True, "weighting": "diagonal"})))
        cases.append((iA, B, ("jacobi", {"filter": True, "weighting": "block"})))
        cases.append((iA, iB, ("jacobi", {"filter": True, "weighting": "local"})))
        cases.append((iA, iB, ("jacobi", {"filter": True, "weighting": "block"})))

        cases.append((iA.tobsr(blocksize=(5, 5)), B, ("jacobi", {"filter": True, "weighting": "block"})))
        cases.append((iA.tobsr(blocksize=(5, 5)), iB, ("jacobi", {"filter": True, "weighting": "block"})))

        cases.append((iA, B, ("energy", {"krylov": "cgnr", "degree": 2})))
        cases.append((iA, iB, ("energy", {"krylov": "cgnr"})))
        cases.append(
            (
                iA.tobsr(blocksize=(5, 5)),
                B,
                ("energy", {"krylov": "cgnr", "degree": 2, "maxiter": 3, "postfilter": {"theta": 0.05}}),
            )
        )
        cases.append(
            (
                iA.tobsr(blocksize=(5, 5)),
                B,
                ("energy", {"krylov": "cgnr", "degree": 2, "maxiter": 3, "prefilter": {"theta": 0.05}}),
            )
        )
        cases.append((iA.tobsr(blocksize=(5, 5)), B, ("energy", {"krylov": "cgnr", "degree": 2, "maxiter": 3})))
        cases.append((iA.tobsr(blocksize=(5, 5)), iB, ("energy", {"krylov": "cgnr"})))

        cases.append((iA, B, ("energy", {"krylov": "gmres"})))
        cases.append((iA, iB, ("energy", {"krylov": "gmres", "degree": 2})))
        cases.append((iA.tobsr(blocksize=(5, 5)), B, ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3})))
        cases.append((iA.tobsr(blocksize=(5, 5)), iB, ("energy", {"krylov": "gmres"})))

        # Simple, imaginary-valued problems
        iA = A + 1.0j * scipy.sparse.eye(A.shape[0], A.shape[1])

        cases.append((iA, B, ("jacobi", {"filter": True, "weighting": "local"})))
        cases.append((iA, B, ("jacobi", {"filter": True, "weighting": "block"})))
        cases.append((iA, iB, ("jacobi", {"filter": True, "weighting": "diagonal"})))
        cases.append((iA, iB, ("jacobi", {"filter": True, "weighting": "block"})))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB, ("jacobi", {"filter": True, "weighting": "block"})))

        cases.append((iA, B, ("energy", {"krylov": "cgnr"})))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB, ("energy", {"krylov": "cgnr"})))

        cases.append((iA, B, ("energy", {"krylov": "gmres"})))
        cases.append((iA.tobsr(blocksize=(4, 4)), iB, ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3})))

        cases.append(
            (
                iA.tobsr(blocksize=(4, 4)),
                iB,
                ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3, "postfilter": {"theta": 0.05}}),
            )
        )
        cases.append(
            (
                iA.tobsr(blocksize=(4, 4)),
                iB,
                ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3, "prefilter": {"theta": 0.05}}),
            )
        )

        A = gauge_laplacian(10, spacing=1.0, beta=0.21)
        B = np.ones((A.shape[0], 1))
        cases.append((A, iB, ("jacobi", {"filter": True, "weighting": "diagonal"})))
        cases.append((A, iB, ("jacobi", {"filter": True, "weighting": "local"})))

        cases.append((A, B, ("energy", {"krylov": "cg"})))
        cases.append((A, iB, ("energy", {"krylov": "cgnr"})))
        cases.append((A, iB, ("energy", {"krylov": "gmres"})))

        cases.append(
            (
                A.tobsr(blocksize=(2, 2)),
                B,
                ("energy", {"krylov": "cgnr", "degree": 2, "maxiter": 3, "postfilter": {"theta": 0.05}}),
            )
        )
        cases.append(
            (
                A.tobsr(blocksize=(2, 2)),
                B,
                ("energy", {"krylov": "cgnr", "degree": 2, "maxiter": 3, "prefilter": {"theta": 0.05}}),
            )
        )
        cases.append((A.tobsr(blocksize=(2, 2)), B, ("energy", {"krylov": "cgnr", "degree": 2, "maxiter": 3})))
        cases.append((A.tobsr(blocksize=(2, 2)), iB, ("energy", {"krylov": "cg"})))
        cases.append((A.tobsr(blocksize=(2, 2)), B, ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3})))

        cases.append(
            (
                A.tobsr(blocksize=(2, 2)),
                B,
                ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3, "postfilter": {"theta": 0.05}}),
            )
        )
        cases.append(
            (
                A.tobsr(blocksize=(2, 2)),
                B,
                ("energy", {"krylov": "gmres", "degree": 2, "maxiter": 3, "prefilter": {"theta": 0.05}}),
            )
        )

        #
        A, B = linear_elasticity((10, 10))
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "diagonal"})))
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "local"})))
        cases.append((A, B, ("jacobi", {"filter": True, "weighting": "block"})))

        cases.append((A, B, ("energy", {"degree": 2})))
        cases.append((A, B, ("energy", {"degree": 3, "postfilter": {"theta": 0.05}})))
        cases.append((A, B, ("energy", {"degree": 3, "prefilter": {"theta": 0.05}})))
        cases.append((A, B, ("energy", {"krylov": "cgnr"})))
        cases.append((A, B, ("energy", {"krylov": "gmres", "degree": 2})))

        # Classic SA cases
        for A, B, smooth in cases:
            ml = smoothed_aggregation_solver(A, B=B, max_coarse=1, max_levels=2, smooth=smooth)
            P = ml.levels[0].P
            B = ml.levels[0].B
            R = ml.levels[1].B
            assert_almost_equal(P * R, B)

        def blocksize(A):
            # Helper Function: return the blocksize of a matrix
            if isspmatrix_bsr(A):
                return A.blocksize[0]
            else:
                return 1

        # Root-node cases
        counter = 0
        for A, B, smooth in cases:
            counter += 1

            if isinstance(smooth, tuple):
                smoother = smooth[0]
            else:
                smoother = smooth

            if smoother == "energy" and (B.shape[1] >= blocksize(A)):
                ic = [("gauss_seidel_nr", {"sweep": "symmetric", "iterations": 4}), None]
                ml = rootnode_solver(
                    A,
                    B=B,
                    max_coarse=1,
                    max_levels=2,
                    smooth=smooth,
                    improve_candidates=ic,
                    keep=True,
                    symmetry="nonsymmetric",
                )
                T = ml.levels[0].T.tocsr()
                Cpts = ml.levels[0].Cpts
                Bf = ml.levels[0].B
                Bf_H = ml.levels[0].BH
                Bc = ml.levels[1].B
                P = ml.levels[0].P.tocsr()

                # P should preserve B in its range, wherever P
                # has enough nonzeros
                mask = (P.indptr[1:] - P.indptr[:-1]) >= B.shape[1]
                assert_almost_equal((P * Bc)[mask, :], Bf[mask, :])
                assert_almost_equal((P * Bc)[mask, :], Bf_H[mask, :])

                # P should be the identity at Cpts
                I1 = eye(T.shape[1], T.shape[1], format="csr", dtype=T.dtype)
                I2 = P[Cpts, :]
                assert_almost_equal(I1.data, I2.data)
                assert_equal(I1.indptr, I2.indptr)
                assert_equal(I1.indices, I2.indices)

                # T should be the identity at Cpts
                I2 = T[Cpts, :]
                assert_almost_equal(I1.data, I2.data)
                assert_equal(I1.indptr, I2.indptr)
                assert_equal(I1.indices, I2.indices)