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