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 )
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 )
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)
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 )
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_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 )
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)