def run_figure_3_7b(): # perturbation size epsilon = 1e-8 # define base matrix B = numpy.array([[0, 0, 1], [1, 0, 0], [0, 1, 0]]) m = B.shape[0] n = 20 C = numpy.diag(numpy.ones(n - 1), -1) A = block_diag((B, 1e2 * C)).todense() A = A + A.T # right hand side b = numpy.eye(m + n, 1) # error matrix F = numpy.zeros((m + n, m + n)) F[m, 0] = epsilon F = F + F.T # error vector f = numpy.eye(m + n, 1) f[m, 0] = epsilon # solve unperturbed linear system solver = linsys.Minres(linsys.LinearSystem(A, b, self_adjoint=True), tol=1e-13) plot_resnorms(solver.resnorms, label=r'$Ax=b$') # solve with perturbed matrix solver_mat = linsys.Minres(linsys.LinearSystem(A + F, b, self_adjoint=True), tol=1e-13) plot_resnorms(solver_mat.resnorms, ls='--', label=r'$(A+F)x_F=b$') # solve with perturbed right hand side solver_mat = linsys.Minres(linsys.LinearSystem(A, b + f, self_adjoint=True), tol=1e-13) plot_resnorms(solver_mat.resnorms, ls='-.', label=r'$\hat{A}x_f=b+f$') # add labels and legend pyplot.ylim(ymax=10) pyplot.legend() pyplot.xlabel(r'Iteration $i$') pyplot.ylabel(r'$\frac{\|r_n\|}{\|b\|}$') pyplot.show()
def get_problem(): '''Returns the problem as a dictionary.''' problem = {} evals = problem['evals'] = numpy.array([-1e-3, -1e-4, -1e-5] + list(1 + numpy.linspace(0, 1, 101))) N = problem['N'] = len(evals) A = problem['A'] = numpy.diag(evals) b = problem['b'] = numpy.ones((N, 1)) b[3:] *= 1e-1 problem['linear_system'] = linsys.LinearSystem(A, b, self_adjoint=True) return problem
def plot_approx(k, G_norm=0., g_norm=0.): problem = get_problem() linear_system = problem['linear_system'] A = problem['A'] b = problem['b'] tol = 1e-6 numpy.random.seed(0) # solve without deflation solver = deflation.DeflatedMinres(linear_system, tol=tol, store_arnoldi=True) arnoldifyer = deflation.Arnoldifyer(solver) ritz = deflation.Ritz(solver) from itertools import cycle G = numpy.random.rand(*A.shape) G += G.T.conj() G *= G_norm / numpy.linalg.norm(G, 2) g = numpy.random.rand(A.shape[0], 1) g *= g_norm / numpy.linalg.norm(g, 2) ls_pert = linsys.LinearSystem(A + G, b + g, self_adjoint=True) for i, color in zip(range(0, k), cycle(defaults.colors)): # actual convergence solver = deflation.DeflatedGmres(ls_pert, U=ritz.get_vectors(list(range(i))), tol=tol) pyplot.semilogy(solver.resnorms, color=color, alpha=0.3) # compute bound bound_approx = deflation.bound_pseudo(arnoldifyer, ritz.coeffs[:, :i], G_norm=G_norm, GW_norm=G_norm, WGW_norm=G_norm, g_norm=g_norm) pyplot.semilogy(bound_approx, color=color, linestyle='dashed')
def app_smw_inv(amat, umat=None, vmat=None, rhsa=None, Sinv=None, savefactoredby=5, return_alu=False, alu=None, krylov=None, krpslvprms={}, krplsprms={}): """compute the sherman morrison woodbury inverse of `A - np.dot(U,V)` applied to an (array)rhs. Parameters ---------- amat : (N,N) sparse matrix main part of `A-UV` umat, vmat : (N,L), (L,N) ndarrays or sparse matrices, optional factored contribution to `amat`, default to `None` rhsa : (N,K) ndarray array or sparse matrix array the inverse of `A-UV` is to be applied to Sinv : (L,L) ndarray, optional the 'small' inverse in the smw formula, defaults to `None` savefactoredby : integer, optional if the number of columns of `rhsa` exceeds this parameter, the lu decomposition of `amat` is stored return_alu : boolean, optional whether to return the lu decomposition of `amat`, defaults to `False` alu : amat.factorized(), optional `lu` factorization of amat krylov : {None, 'gmres'}, optional whether or not to use an iterative solver, defaults to `None` krpslvprms : dictionary, optional to specify parameters of the linear solver for use in Krypy, e.g., * 'x0', nparray: initial guess * tolerance * max number of iterations * 'convstatsl', list: for convergence statistics defaults to `None` krplsprms : dictionary, optional parameters to define the linear system like * preconditioner Returns ------- , : (N,K) ndarray the inverse of `A-UV` applied to rhsa """ if krylov is not None: import krypy.linsys as kls def auvb(v): if umat is None: return amat * v else: return amat * v - mm_dnssps(umat, mm_dnssps(vmat, v)) auvblo = spsla.LinearOperator(amat.shape, matvec=auvb, dtype='float64') auvirhs = [] try: citcl = [] for rhscol in range(rhsa.shape[1]): crhs = rhsa[:, rhscol] krplinsys = kls.LinearSystem(A=auvblo, b=crhs, **krplsprms) solinst = kls.Gmres(krplinsys, **krpslvprms) auvirhs.append(solinst.xk) # solinst.xk = None # strip off solution vector for stats citcl.append(solinst.resnorms) krpslvprms['convstatsl'].append(citcl) except KeyError: pass # no stats return np.asarray(auvirhs)[:, :, 0].T else: if rhsa.shape[1] >= savefactoredby or return_alu: try: alu = spsla.factorized(amat) except (NotImplementedError, TypeError): alu = amat elif alu is None: alu = amat # auvirhs = np.zeros(rhsa.shape) auvirhs = [] for rhscol in range(rhsa.shape[1]): crhs = rhsa[:, rhscol] # branch with u and v present if umat is not None: if Sinv is None: Sinv = get_Sinv_smw(alu, umat, vmat) # the corrected rhs: (I + U*Sinv*V*Ainv)*rhs try: # if Alu comes factorized, e.g. LU-factored - fine aicrhs = alu(crhs) except TypeError: aicrhs = spsla.spsolve(alu, crhs) if sps.isspmatrix(vmat): crhs = crhs + mm_dnssps(umat, np.dot(Sinv, vmat * aicrhs)) else: crhs = crhs + mm_dnssps(umat, np.dot(Sinv, np.dot(vmat, aicrhs))) try: # auvirhs[:, rhscol] = alu(crhs) auvirhs.append(alu(crhs)) except TypeError: # auvirhs[:, rhscol] = spsla.spsolve(alu, crhs) auvirhs.append(spsla.spsolve(alu, np.array(crhs))) if return_alu: return np.asarray(auvirhs).T, alu else: return np.asarray(auvirhs).T