LDPC编译码

LDPC编译码,第1张

LDPC编译码

文章目录
  • LDPC编译码
  • 前言
  • 一、码字
    • 1.校验矩阵
      • a.适用于matlab的校验矩阵
      • b.适用于 C的校验矩阵
      • c.适用于python的校验矩阵
    • 2.生成矩阵
      • a.基于matlab的生成矩阵构造
      • b.基于python的生成矩阵读取
      • c.基于python的随机码字生成


前言

低密度奇偶校验(LDPC)码是目前5G通信常用的信道编码码字的一种,其具有接近香农极限的编译码性能。本文主要记录对LDPC码研究时常用的一些网站以及便捷的一些代码介绍,如有错误欢迎指出,大家一起学习。
PS:硕士期间有幸跟随导师了解这一领域,并进行了相关的研究,故借此进行记录。

一、码字

LDPC码的编码方式有很多种,本节主要介绍实验过程中常用的一些码字。

1.校验矩阵

详情可以从ldpc码校验矩阵获取。

a.适用于matlab的校验矩阵

使用matlab进行译码的校验矩阵要求是位置索引需要从1开始,或者为完整0,1矩阵。此处给出一份python的转换代码,将位置索引从0开始的转换为从1开的。注:从上面网址中下载的校验矩阵的位置索引是从1开始的。

def gen_m_mtx(file_path,dec_path):
    new_mtx = []
    with open(file_path,'r') as fp:
        lines = tuple(line for line in fp if len(line.split()) > 0)
        max_ind = max(tuple(max(map(int, line.split())) for line in lines))
        min_ind = min(tuple(min(map(int, line.split())) for line in lines))
        if min_ind not in [0, 1]: raise Exception('Minimum index is not 0 or 1.')
        mtx = np.zeros((len(lines), max_ind + (0 if min_ind == 1 or str(max_ind) in file_path  else 1)), int)
        if max_ind+1 == mtx.shape[1]:
            for line in lines:
                sdataa = line.split()
                data = []
                for sdata in sdataa:
                    data.append(int(sdata)+1)
                new_mtx.append(data)
        with open(dec_path,'w') as nfp:
            nfp.write(str(new_mtx).replace('], ',' \n').replace(']]',' ').replace(',','').replace('[',''))
b.适用于 C的校验矩阵

由于C语言数据存储位置索引默认都是从0开始的,因此对于C的译码程序来说,校验矩阵中1的位置索引需要从0开始,相同的,此处给出对应位置索引从1转换到0的代码。

def gen_c_mtx(file_path,dec_path):
    new_mtx = []
    with open(file_path,'r') as fp:
        lines = tuple(line for line in fp if len(line.split()) > 0)
        max_ind = max(tuple(max(map(int, line.split())) for line in lines))
        min_ind = min(tuple(min(map(int, line.split())) for line in lines))
        if min_ind not in [0, 1]: raise Exception('Minimum index is not 0 or 1.')
        mtx = np.zeros((len(lines), max_ind + (0 if min_ind == 1 or str(max_ind) in file_path  else 1)), int)
        if max_ind == mtx.shape[1]:
            for line in lines:
                sdataa = line.replace('_0','').split()
                data = []
                for sdata in sdataa:
                    data.append(int(sdata)-1)
                new_mtx.append(data)
        with open(dec_path,'w') as nfp:
            nfp.write(str(new_mtx).replace('], ',' \n').replace(']]',' ').replace(',','').replace('[',''))
c.适用于python的校验矩阵

前面给出的两份代码都是基于python做的矩阵文本转换,因此,在python中读取矩阵会十分简单,并且可以根据相关条件做到自动识别,因此针对python给出针对按照校验矩阵行数读取校验矩阵的代码。

def load_parity_mtx(file_path):
    with open(file_path, 'r') as fp:
        lines = tuple(line for line in fp if len(line.split()) > 0)
        max_ind = max(tuple(max(map(int, line.split())) for line in lines))
        min_ind = min(tuple(min(map(int, line.split())) for line in lines))
        if min_ind not in [0, 1]: raise Exception('Minimum index is not 0 or 1.')
        mtx = np.zeros((len(lines), max_ind + (0 if min_ind == 1 or str(max_ind) in file_path  else 1)), int)
        chk_num = 1
        for line in lines:
            for var_num in map(int, line.split()):
                if max_ind == mtx.shape[1]:
                    mtx[chk_num - 1, var_num - 1] = 1
                else:
                    mtx[chk_num - 1, var_num] = 1               
            chk_num += 1
        if max_ind == 1:
            mtx = []
            for line in lines:
                line = line.replace('\n','')
                line = line.split(" ", -1)
                list_value = []
                for data in line:
                    data = float(data)
                    list_value.append(data)
                mtx.append(list_value)
            mtx = np.array(mtx)
        return mtx
2.生成矩阵

上面的网址中,有些码字是给出了其对应的生成矩阵的,但也有很多的码字只给出了校验矩阵,因此,在有些情况下需要测试随机码字的译码性能就需要有生成矩阵的支持。

a.基于matlab的生成矩阵构造

校验矩阵与生成矩阵的关系为两者的矩阵乘的模二和为0。根据这个关系可以由校验矩阵得到生成矩阵。代码如下:

//=====================================================//
function H = GenHirr(file,col)
 %A=dlmread(file,' ');
 A=dlmread(file);
 [A_row,A_col] = size(A);
 H = zeros(A_row,col);
 zeroStart = find(A(:,1) ==0);
 for i=1:A_row
     for j=1:A_col
         if(A(i,j) ~= 0)
             if(zeroStart)
                H(i,A(i,j)+1) = 1;
             else
                H(i,A(i,j)) = 1; 
             end
         elseif(j == 1)
             H(i,A(i,j)+1) = 1;
         end
     end
 end
end
//=====================================================//

//=====================================================//
function H1 = makeHStdForm(H)
rows = size(H, 1);
cols = size(H, 2);

r = 1;
for c = cols - rows + 1:cols
    if H(r,c) == 0
        % Swap needed
        for r2 = r + 1:rows
            if H(r2,c) ~= 0
                tmp = H(r, :);
                H(r, :) = H(r2, :);
                H(r2, :) = tmp;
            end
        end

        % Ups...
        if H(r,c) == 0
            error('H is singular');
        end
    end

    % Forward substitute
    for r2 = r + 1:rows
        if H(r2, c) == 1
            H(r2, :) = xor(H(r2, :), H(r, :));
        end
    end

    % Back Substitution
    for r2 = 1:r - 1
        if H(r2, c) == 1
            H(r2, :) = xor(H(r2, :), H(r, :));
        end
    end

    % Next row
    r = r + 1;
end
H1 = H;
end
//=====================================================//

//=====================================================//
function G = hMat2GMat(H)
H1 = makeHStdForm(H);
G = gen2par(H1);
end
//=====================================================//


//=====================================================//
//产生生成示例,生成矩阵为01构成的矩阵
H = GenHirr('720_400.txt',720);
[hRow,hCol] = size(H);
G = hMat2GMat(H);
fid = fopen('720_400_G.txt','w');
fprintf(fid,[repmat('%d ', 1, size(G,2)), '\n'], G');   
//=====================================================//
b.基于python的生成矩阵读取
def load_gen_mtx(file_path):
    with open(file_path, 'r') as fp:
        gens = fp.readlines()
        mtx = []
        for g in gens:
            g = g.replace('\n','')
            g = g.split(" ", -1)
            ber = []
            for tmp_float in g[:-1]:
                ber.append(int(tmp_float))
            mtx.append(ber)
        return np.array(mtx)
c.基于python的随机码字生成
class Code:
    def __init__(self, gen_mtx, parity_mtx):
        self.gen_mtx, self.parity_mtx = gen_mtx, parity_mtx

        if gen_mtx is not None:
            k, n = gen_mtx.shape
            #messages = mu.binary_vectors(k)
            #print(np.random.randint(0,2,size=k))
            messages = np.random.randint(0,2,size=(1,k))
            #print(messages)
            self.cb = (messages @ gen_mtx) % 2

            # check if GH^T = 0
            #print(np.sum((self.cb @ parity_mtx.T) % 2))
            assert (np.sum((self.cb @ parity_mtx.T) % 2) == 0)
            #assert (self.cb[0].sum() == 0)  # all zeros cw
            #assert (self.cb[-1].sum() == n)  # all ones cw

    def get_k(self): return self.get_n() - self.parity_mtx.shape[0]

    def get_n(self): return self.parity_mtx.shape[1]

    def get_random_code(self,batchsize=1,seed = None):
        k, n = self.gen_mtx.shape
        if seed != None:
            np.random.seed(seed)
        messages = np.random.randint(0,2,size=(batchsize,k))
        self.cb = (messages @ self.gen_mtx) % 2
        assert (np.sum((self.cb @ self.parity_mtx.T) % 2) == 0)
        return self.cb

    def save_random_c(self,path,batchsize=1,seed = None):
        k, n = self.gen_mtx.shape
        if seed != None:
            np.random.seed(seed)
        messages = np.random.randint(0,2,size=(batchsize,k))
        c_code = (messages @ self.gen_mtx) % 2
        assert (np.sum((c_code @ self.parity_mtx.T) % 2) == 0)
        np.set_printoptions(threshold=np.inf)
        with open(path,'w') as f:
            f.write(str(c_code).replace('[','').replace(']','').replace('\n',''))

#生成示例
if __name__ == "__main__":
    code = Code(gmtx,Hmtx)
    code.save_random_c(dec_path+'codeword_rand.txt')

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/798139.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存