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()
Exemple #2
0
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
Exemple #3
0
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')
Exemple #4
0
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