def test_minres_lanczos(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )
        self._create_sparse_herm_indef_matrix(4)

        # Solve using MINRES.
        tol = 1.0e-9
        out = nm.minres( A, rhs, x0, tol=tol, maxiter=num_unknowns,
                         explicit_residual=False, return_basis=True,
                         full_reortho=True
                         )

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), 0.0,
                                delta=tol )
        # Check if Lanczos relation holds
        res = A*out['Vfull'][:,0:-1] - np.dot(out['Vfull'], out['Hfull'])
        self.assertAlmostEqual( np.linalg.norm(res), 0.0, delta=1e-8 )
        # Check if Lanczos basis is orthonormal w.r.t. inner product
        max_independent = min([num_unknowns,out['Vfull'].shape[1]])
        res = np.eye(max_independent) - \
                np.dot( out['Pfull'][:,0:max_independent].T.conj(),
                        out['Vfull'][:,0:max_independent] )
        self.assertAlmostEqual( np.linalg.norm(res), 0.0, delta=1e-8 )
    def test_minres_deflation(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )

        # get projection
        from scipy.sparse.linalg import eigs
        num_vecs = 6
        D, W = eigs(A, k=num_vecs, v0=np.ones((num_unknowns,1)))

        # Uncomment next lines to perturb W
        #W = W + 1.e-10*np.random.rand(W.shape[0], W.shape[1])
        #from scipy.linalg import qr
        #W, R = qr(W, mode='economic')

        AW = nm._apply(A, W)
        P, x0new = nm.get_projection( W, AW, rhs, x0 )

        # Solve using MINRES.
        tol = 1.0e-9
        out = nm.minres( A, rhs, x0new, Mr=P, tol=tol, maxiter=num_unknowns-num_vecs, full_reortho=True, return_basis=True )

        # TODO: move to new unit test
        o = nm.get_p_ritz( W, AW, out['Vfull'], out['Hfull'] )
        ritz_vals, ritz_vecs = nm.get_p_ritz( W, AW, out['Vfull'], out['Hfull'] )

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), 0.0, delta=tol )
Exemple #3
0
    def test_minres_lanczos(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))
        self._create_sparse_herm_indef_matrix(4)

        # Solve using MINRES.
        tol = 1.0e-9
        out = nm.minres(A,
                        rhs,
                        x0,
                        tol=tol,
                        maxiter=num_unknowns,
                        explicit_residual=False,
                        return_basis=True,
                        full_reortho=True)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
        # Check if Lanczos relation holds
        res = A * out['Vfull'][:, 0:-1] - np.dot(out['Vfull'], out['Hfull'])
        self.assertAlmostEqual(np.linalg.norm(res), 0.0, delta=1e-8)
        # Check if Lanczos basis is orthonormal w.r.t. inner product
        max_independent = min([num_unknowns, out['Vfull'].shape[1]])
        res = np.eye(max_independent) - \
                np.dot( out['Pfull'][:,0:max_independent].T.conj(),
                        out['Vfull'][:,0:max_independent] )
        self.assertAlmostEqual(np.linalg.norm(res), 0.0, delta=1e-8)
    def test_minres_sparse_indef_precon(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        M = self._create_hpd_matrix( num_unknowns )
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )

        # Solve using spsolve.
        xexact = scipy.sparse.linalg.spsolve(A, rhs)
        xexact = np.reshape(xexact, (len(xexact),1))
        # Solve using MINRES.
        tol = 1.0e-10
        out = nm.minres( A, rhs, x0, tol=tol, maxiter=100*num_unknowns, explicit_residual=True, exact_solution=xexact, M=M)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)

        # compute M-norm of residual
        res = rhs - A * out['xk']
        Mres = np.dot(M, res)
        norm_res = np.sqrt(np.vdot(res, Mres))

        # compute M-norm of rhs
        Mrhs = np.dot(M, rhs)
        norm_rhs = np.sqrt(np.vdot(rhs, Mrhs))

        # Check the residual.
        self.assertAlmostEqual( norm_res/norm_rhs, 0.0, delta=tol )
        # Check error.
        self.assertAlmostEqual( np.linalg.norm(xexact - out['xk']) - out['errvec'][-1], 0.0, delta=1e-10 )
Exemple #5
0
    def test_minres_sparse_indef(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))

        # Solve using spsolve.
        xexact = scipy.sparse.linalg.spsolve(A, rhs)
        xexact = np.reshape(xexact, (len(xexact), 1))
        # Solve using MINRES.
        tol = 1.0e-10
        out = nm.minres(A,
                        rhs,
                        x0,
                        tol=tol,
                        maxiter=4 * num_unknowns,
                        explicit_residual=True,
                        exact_solution=xexact)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
        # Check error.
        self.assertAlmostEqual(np.linalg.norm(xexact - out['xk']) -
                               out['errvec'][-1],
                               0.0,
                               delta=1e-10)
Exemple #6
0
    def test_get_ritz(self):
        N = 10
        A = scipy.sparse.spdiags(range(1, N + 1), [0], N, N)
        b = np.ones((N, 1))
        x0 = np.ones((N, 1))

        # 'last' 2 eigenvectors
        W = np.zeros((N, 2))
        W[-2, 0] = 1.
        W[-1, 1] = 1
        AW = A * W

        # Get the projection
        P, x0new = nm.get_projection(W, AW, b, x0)

        # Run MINRES (we are only interested in the Lanczos basis and tridiag matrix)
        out = nm.minres(A,
                        b,
                        x0new,
                        Mr=P,
                        tol=1e-14,
                        maxiter=11,
                        full_reortho=True,
                        return_basis=True)

        # Get Ritz pairs
        ritz_vals, ritz_vecs = nm.get_p_ritz(W, AW, out['Vfull'], out['Hfull'])

        # Check Ritz pair residuals
        #ritz_res_exact = A*ritz_vecs - np.dot(ritz_vecs,np.diag(ritz_vals))
        #for i in range(0,len(ritz_vals)):
        #norm_ritz_res_exact = np.linalg.norm(ritz_res_exact[:,i])
        #self.assertAlmostEqual( abs(norm_ritz_res[i] - norm_ritz_res_exact), 0.0, delta=1e-13 )

        # Check if Ritz values / vectors corresponding to W are still there ;)
        order = np.argsort(ritz_vals)
        # 'last' eigenvalue
        self.assertAlmostEqual(abs(ritz_vals[order[-1]] - N), 0.0, delta=1e-13)
        self.assertAlmostEqual(abs(ritz_vals[order[-2]] - (N - 1)),
                               0.0,
                               delta=1e-13)
        # now the eigenvectors
        self.assertAlmostEqual(abs(nm._ipstd(ritz_vecs[:, order[-1]], W[:,
                                                                        1])),
                               1.0,
                               delta=1e-13)
        self.assertAlmostEqual(abs(nm._ipstd(ritz_vecs[:, order[-2]], W[:,
                                                                        0])),
                               1.0,
                               delta=1e-13)
    def test_minres_dense_complex(self):
        # Create regular dense problem.
        num_unknowns = 3
        A = np.array( [[1,-2+1j,0], [-2-1j,2,-1], [0,-1,3]] )
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )

        # Solve using MINRES.
        tol = 1.0e-14
        out = nm.minres( A, rhs, x0, tol=tol )

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - np.dot(A, out['xk'])
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), 0.0, delta=tol )
    def test_minres_dense(self):
        # Create regular dense problem.
        num_unknowns = 5
        A = self._create_sym_indef_matrix( num_unknowns )
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )

        # Solve using MINRES.
        tol = 1.0e-13
        out = nm.minres( A, rhs, x0, tol=tol )

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - np.dot(A, out['xk'])
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), 0.0, delta=tol )
    def test_minres_sparse_hpd(self):
        # Create sparse HPD problem.
        num_unknowns = 100
        A = self._create_sparse_hpd_matrix(num_unknowns)
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )

        # Solve using MINRES.
        tol = 1.0e-10
        out = nm.minres( A, rhs, x0, tol=tol)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A*out['xk']
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), 0.0, delta=tol )
        # Is last residual in relresvec equal to explicitly computed residual?
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), out['relresvec'][-1], delta=tol )
Exemple #10
0
    def test_minres_dense_complex(self):
        # Create regular dense problem.
        num_unknowns = 3
        A = np.array([[1, -2 + 1j, 0], [-2 - 1j, 2, -1], [0, -1, 3]])
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))

        # Solve using MINRES.
        tol = 1.0e-14
        out = nm.minres(A, rhs, x0, tol=tol)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - np.dot(A, out['xk'])
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
Exemple #11
0
    def test_minres_dense(self):
        # Create regular dense problem.
        num_unknowns = 5
        A = self._create_sym_indef_matrix(num_unknowns)
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))

        # Solve using MINRES.
        tol = 1.0e-13
        out = nm.minres(A, rhs, x0, tol=tol)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - np.dot(A, out['xk'])
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
Exemple #12
0
    def test_minres_deflation(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))

        # get projection
        from scipy.sparse.linalg import eigs
        num_vecs = 6
        D, W = eigs(A, k=num_vecs, v0=np.ones((num_unknowns, 1)))

        # Uncomment next lines to perturb W
        #W = W + 1.e-10*np.random.rand(W.shape[0], W.shape[1])
        #from scipy.linalg import qr
        #W, R = qr(W, mode='economic')

        AW = nm._apply(A, W)
        P, x0new = nm.get_projection(W, AW, rhs, x0)

        # Solve using MINRES.
        tol = 1.0e-9
        out = nm.minres(A,
                        rhs,
                        x0new,
                        Mr=P,
                        tol=tol,
                        maxiter=num_unknowns - num_vecs,
                        full_reortho=True,
                        return_basis=True)

        # TODO: move to new unit test
        o = nm.get_p_ritz(W, AW, out['Vfull'], out['Hfull'])
        ritz_vals, ritz_vecs = nm.get_p_ritz(W, AW, out['Vfull'], out['Hfull'])

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
    def test_get_ritz(self):
        N = 10
        A = scipy.sparse.spdiags( range(1,N+1), [0], N, N)
        b = np.ones( (N,1) )
        x0 = np.ones( (N,1) )

        # 'last' 2 eigenvectors
        W = np.zeros( (N,2) )
        W[-2,0]=1.
        W[-1,1]=1
        AW = A*W

        # Get the projection
        P, x0new = nm.get_projection(W, AW, b, x0)

        # Run MINRES (we are only interested in the Lanczos basis and tridiag matrix)
        out = nm.minres(A, b, x0new, Mr=P, tol=1e-14, maxiter=11,
                        full_reortho=True,
                        return_basis=True
                        )

        # Get Ritz pairs
        ritz_vals, ritz_vecs = nm.get_p_ritz(W, AW,
                                             out['Vfull'],
                                             out['Hfull']
                                             )

        # Check Ritz pair residuals
        #ritz_res_exact = A*ritz_vecs - np.dot(ritz_vecs,np.diag(ritz_vals))
        #for i in range(0,len(ritz_vals)):
            #norm_ritz_res_exact = np.linalg.norm(ritz_res_exact[:,i])
            #self.assertAlmostEqual( abs(norm_ritz_res[i] - norm_ritz_res_exact), 0.0, delta=1e-13 )

        # Check if Ritz values / vectors corresponding to W are still there ;)
        order = np.argsort(ritz_vals)
        # 'last' eigenvalue
        self.assertAlmostEqual( abs(ritz_vals[order[-1]] - N), 0.0, delta=1e-13 )
        self.assertAlmostEqual( abs(ritz_vals[order[-2]] - (N-1)), 0.0, delta=1e-13 )
        # now the eigenvectors
        self.assertAlmostEqual( abs(nm._ipstd(ritz_vecs[:,order[-1]],W[:,1])), 1.0, delta=1e-13 )
        self.assertAlmostEqual( abs(nm._ipstd(ritz_vecs[:,order[-2]],W[:,0])), 1.0, delta=1e-13 )
Exemple #14
0
    def test_minres_sparse_hpd(self):
        # Create sparse HPD problem.
        num_unknowns = 100
        A = self._create_sparse_hpd_matrix(num_unknowns)
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))

        # Solve using MINRES.
        tol = 1.0e-10
        out = nm.minres(A, rhs, x0, tol=tol)

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
        # Is last residual in relresvec equal to explicitly computed residual?
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               out['relresvec'][-1],
                               delta=tol)