def generalized_orthogonal_matching_pursuit(A, b, s0=None, tol=1e-5, maxnnz=None, toarray=True,
                                            iter_lim=None, solver='eig', atol=1e-3, btol=1e-3, conlim=1e+4, N=3):
    m, n = A.shape
    if maxnnz is None:
        maxnnz = m // 2
    if s0 is None or len(s0) == 0:
        support = np.array([], dtype=int)
        xnz = np.array([])
        r = b.copy()
    else:
        support = np.array(s0, dtype=int)
        xnz, r = lstsq(A, b, support=support,
                       iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)

    # main loop
    count = 0
    while len(support) < min(maxnnz, m/N) and linalg.norm(r) > tol:
        count += 1
        c = splinalg.aslinearoperator(A).rmatvec(r)        # c = A.conj().T.dot(r)
        s = np.argsort(-np.abs(c))
        support = np.union1d(support, s[:N])
        xnz, r = lstsq(A, b, support=support,
                       iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)
        # xnz = linalg.lstsq(A[:,T],b)[0]
        #r = b - A.dot(x)
    return spvec(n, (xnz, support), toarray=toarray), r, count
def orthogonal_matching_pursuit(A, b, s0=None, tol=1e-5, maxnnz=None, toarray=True,
                                iter_lim=None, solver='eig', atol=1e-3, btol=1e-3, conlim=1e+4):
    m, n = A.shape
    if maxnnz is None:
        maxnnz = m // 2
    if s0 is None or len(s0) == 0:
        support = np.array([], dtype=int)
        xnz = np.array([])
        r = b.copy()
    else:
        support = np.array(s0, dtype=int)
        xnz, r = lstsq(A, b, support=support,
                       iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)

    # main loop
    count = 0
    order = []
    while len(support) < maxnnz and linalg.norm(r) > tol:
        count += 1
        s = np.argmax(np.abs( splinalg.aslinearoperator(A).rmatvec(r) ))
        support = np.union1d(support, [s])
        order.append(s)
        xnz, r = lstsq(A, b, support=support,
                       iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)
    return spvec(n, (xnz, support), toarray=toarray), r, count, order
def orthogonal_matching_pursuit_using_linearoperator(A, b, s0=None, tol=1e-5, maxnnz=None, toarray=True,
                                 iter_lim=None, solver='eig', atol=1e-3, btol=1e-3, conlim=1e+4):
    m, n = A.shape
    if maxnnz is None:
        maxnnz = m // 2
    if s0 is None or len(s0) == 0:
        support = np.array([], dtype=int)
        xnz = np.array([])
        r = b.copy()
    else:
        As = np.zeros((m,len(support)), dtype=A.dtype)
        support = np.array(s0, dtype=int)
        h = np.zeros(n)
        for s in support:
            h = np.zeros(n)
            h[s] = 1.0
            As[:,s] = A.matvec(h)
        xnz, r = lstsq(As, b, solver=solver)

    # main loop
    count = 0
    order = []
    As = np.empty((m,0), dtype=A.dtype)
    while len(support) < maxnnz and linalg.norm(r) > tol:
        count += 1
        s = np.argmax(np.abs( splinalg.aslinearoperator(A).rmatvec(r) ))
        support = np.union1d(support, [s])
        order.append(s)
        h = np.zeros(n)
        h[s] = 1.0
        As = np.append(As, np.atleast_2d(A.matvec(h)).T, axis=1)
        xnz, r = lstsq(As, b, solver=solver)

    return spvec(n, (xnz, order), toarray=toarray), r, count, order, As
def matching_pursuit(A, b, tol=1e-5, maxiter=None, toarray=True):
    m, n = A.shape
    if maxiter is None:
        maxiter = m
    xnz = []
    support = []
    r = b.copy()

    # main loop
    count = 0
    while linalg.norm(r) > tol and count < maxiter:
        count += 1
        c = splinalg.aslinearoperator(A).rmatvec(r)        # c = A.conj().T.dot(r)
        s = np.argmax(np.abs(c))
        support.append(s)
        xs = c[s] / linalg.norm(A[:,s])
        xnz.append(xs)
        r -= A[:,s] * xs
    return spvec(n, (xnz, support), duplicate=True, toarray=toarray), r, count
def subspace_pursuit(A, b, K=None, s0=None, maxiter=None, toarray=True,
                     iter_lim=None, solver='eig', atol=1e-3, btol=1e-3, conlim=1e+4):
    m, n = A.shape
    if K is None:
        #K = m // 4
        K = int(0.5*m / np.log2(n/m))
        K = min(K, m//4)
    if maxiter is None:
        maxiter = K
    if s0 is None or len(s0) == 0:
        c = splinalg.aslinearoperator(A).rmatvec(b)
        supp = np.array(np.argsort(-np.abs(c))[:K], dtype = int)
    else:
        supp = np.array(s0, dtype=int)
    xnzp, r = lstsq(A, b, support=supp,
                    iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)

    #Told = np.array([], dtype = int)
    normrold = np.inf
    normr = linalg.norm(r)
    
    # main loop
    count = 0
    while normr < normrold and count < maxiter:
        count += 1
        normrold = normr
        support = supp
        xnz = xnzp
        # T = union of T and {K indices corresponding to the largest magnitude entries in the vector A'*r}
        c = splinalg.aslinearoperator(A).rmatvec(r)
        supp = np.union1d(supp, np.argsort(-np.abs(c))[:K])
        xnzp, r = lstsq(A, b, support=supp,
                        iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)
        # T = {K indices corresponding to the largest elements of xp}
        supp = supp[np.argsort(-np.abs(xnzp))[:K]]
        xnzp, r = lstsq(A, b, support=supp,
                        iter_lim=iter_lim, solver=solver, atol=atol, btol=btol, conlim=conlim)
        normr = linalg.norm(r)
    return spvec(n, (xnz, support), toarray=toarray), r, count
Exemple #6
0
def lstsq(A,
          B,
          support=None,
          x0=None,
          iter_lim=None,
          solver='eig',
          atol=1e-3,
          btol=1e-3,
          conlim=1e+4):

    m, n = A.shape
    if support is not None:
        ls = list(support)
    else:
        ls = range(n)
    s = len(ls)
    B = np.atleast_2d(B.T).T  # (m,)->(m,1), (m,n)
    c = B.shape[1]

    # if A is a numpy array
    if type(A) is np.ndarray:
        As = A[:, ls]
        if solver == 'eig':
            Xnz = linalg.solve(As.conj().T.dot(As),
                               As.conj().T.dot(B)).reshape(
                                   (s,
                                    c))  # Using solve (eig-based) is faster ..
        else:
            Xnz = linalg.lstsq(
                As,
                B,
                overwrite_a=True,
                overwrite_b=True,
                lapack_driver=solver)[
                    0]  # I prefer this for the better condition number ..

    else:
        # Assuming A to be a linear operator, create a linear operator of A[:,ls]
        #A = splinalg.aslinearoperator(A)
        As = splinalg.LinearOperator(
            (A.shape[0], len(ls)),
            matvec=lambda xnz: A.matvec(spvec(A.shape[1], (xnz, ls))),
            rmatvec=lambda y: A.rmatvec(y)[ls])

        if iter_lim is None:
            iter_lim = s
        Xnz = np.zeros((s, c))
        for j in range(c):
            Xnz[:, j] = splinalg.lsqr(As,
                                      B[:, j],
                                      damp=0.0,
                                      atol=atol,
                                      btol=btol,
                                      conlim=conlim,
                                      iter_lim=iter_lim,
                                      show=False,
                                      calc_var=False)[0]
            #Xnz[:,j] = lstsq_cg(As, B[:,j], x0=x0, maxiter=maxiter)[0]

    R = B - As.dot(Xnz)
    if c == 1:
        R = R.ravel()
        Xnz = Xnz.ravel()
    return Xnz, R