压缩感知正交匹跟踪算法(OMP)代码实现之单一向量的求解

研究生导师的方向是压缩感知,导师让我这个暑假将压缩感知尽可能的搞懂,方便开学之后研究工作。

压缩感知网上资料很多,压缩感知就是将稀疏向量通过一个压缩矩阵压缩,使其存储的数据量减少,在通过压缩感知的算法吧原先的稀疏向量求解出来。具体细节网上文献也很多,我就不多赘述。这篇文章主要是对于压缩感知中一个常用算法正交匹配跟踪算法的python代码实现。

关于正交匹配跟踪算法代码实现的文章我打算写三篇,写这三篇文章的初衷是我发现网上关于OMP算法的代码很少,有也是要么matlab实现,要么是python2.7实现的。基本没看到有人用python3.6去实现,所以打算自己实现一遍。第一篇主要是求解单一向量;第二篇是某个信号的回复,比如多个三角函数的叠加信号;最后一篇将是图片的信号的恢复。

这个代码首先是参考一篇举例文章实现的,要看懂我的代码一定要去看这篇文章:

英文原版:https://korediantousman.staff.telkomuniversity.ac.id/files/2017/08/main-1.pdf

中文版:https://zhuanlan.zhihu.com/p/52276805

'''
这个代码主要实现了《Introduction to Orthogonal Matching Pursuit》举得例子
作者:Kyda
时间:7.18.2019
'''

import numpy as np
import numpy.linalg as lg

def get_matri_new_plus(A):
    '''
    求A矩阵的伪逆
    :param A: 输入矩阵
    :return A_new: 求解的伪逆矩阵
    '''
    A_new = A.T.dot(A)
    if A_new.ndim < 2:
        A_new =  1 / A_new
        A_new = A_new * A.T
    else:
        A_new = lg.inv(A_new)
        A_new = A_new.dot(A.T)
    return A_new


def get_A_ba(A):
    '''
    求解A_ba,也就是矩阵列向量单位化
    :param A: 输入矩阵
    :return A_new: 返回列向量单位后的矩阵
    '''
    A_new = A.T
    for row in range(A_new.shape[0]):
        norm2 = lg.norm(A_new[row], ord=2)           # 求向量的2范数
        A_new[row] /= norm2                          # 单位化
    return A_new




def find_pos_VecInMatrix(A, v):
    '''
    求解某个向量在矩阵中的相应行位置
    :param A: 输入矩阵
    :param v: 输入向量
    :return pos: 位置
    '''
    A_rownum = A.shape[0]    # 矩阵行的数量
    for pos in range(A_rownum):
        if (v==A[pos]).all():           # 判断向量v和矩阵中的某一行是否相等
            return pos


x = np.array([0, 8, 1, 2])
A = np.array([[-0.8, 0.3, 1, 0.4],
              [-0.2, 0.4, -0.3, -0.4],
              [0.2, 1, -0.1, 0.8]])
N = A.shape[0]                   # 矩阵行的数量
y = A.dot(x)                     # 获取y
r = y                            # 初始化残差residue
A_ba = get_A_ba(A.copy())        # 初始化A矩阵
A_ba1 = A_ba                     # 复制
A_new = None
L_p = None
pos_selected_v = []      # 用于存储被选择向量的在矩阵A中位置
for times in range(N):
    w = A_ba.dot(r)                             # 求剩余向量的贡献
    pos = np.argmax(abs(w))                     # 找到贡献最大值的对应位置
    b_k = A_ba[pos]                             # 求最大贡献值所对应的向量, 即最大贡献向量
    A_ba = np.delete(A_ba, pos, axis=0)         # 删除A_ba向量中的最大贡献向量
    pos1 = find_pos_VecInMatrix(A_ba1, b_k)     # 在找到最大贡献向量在原有矩阵中的位置
    pos_selected_v.append(pos1)                 # 保存
    if A_new is None:                          # 将最大贡献向量(未单位化的)加入A_new矩阵
        A_new = A.T[pos1]
    else:
        A_new = np.c_[A_new, A.T[pos1]]
    A_new_plus = get_matri_new_plus(A_new)      # 求A_new_plus
    L_p = A_new_plus.dot(y)                     # 解最小二乘解
    r = y - A_new.dot(L_p)                      # 求残差


x_ans = [0] * (N+1)                             # 初始化求解向量
for item in range(N):                           # 将求出来的值写入求解向量
    pos = pos_selected_v[item]
    x_r = L_p[item]
    x_ans[pos] = round(x_r, 2)
print(x_ans)
发布了67 篇原创文章 · 获赞 77 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/weixin_37720172/article/details/96422153