实验六 |
您所在的位置:网站首页 › python信道编码 › 实验六 |
信息论编码实验3~9连载,更多看专栏。 线性分组码的MATLAB实现 一、线性分组码原理介绍1.1 信道编码基本概念1.2 分组编码1.2.1 编码1.2.2 译码1.2.3 线性分组码的距离和纠错能力 二、(7,4)汉明码编译码实例三、代码展示及运行结果3.1 (7,4)汉明码编码3.2 (7,4)汉明码译码3.3 (7,4)汉明码性能探究 四、程序自评价 一、线性分组码原理介绍 1.1 信道编码基本概念信道编码 也叫 差错控制编码,指在将要传输的信息序列中人为的添加一些保护成分(监督码元),从而在接收端译码时可以进行自动纠错(当然,这种纠错能力是有限的),从而增强了信号的抗干扰能力。 假设 发送序列长度 为 n,其中信息码元数为 k,监督码元数为 n-k,则: 编码效率(码率)= k / n; 冗余度= (n-k) / k; 信道编码分为 分组编码 和 卷积编码。两者都是将原始信息流按长度 k 分组,再按照各自的编码规则映射成 长度为n的码组 进行发送。不同的是,对于每个码组的监督码元(长度为n-k),分组编码仅与本码组的 k 个信息码元有关,而卷积编码则同时与前 N-1 个码组及本码组的(共N*k个)信息码元有关(其中,N 被称为 编码约束度 )。 于是,根据上述定义的变量,对于上述两类编码有命名: (n,k)分组码; (n,k,N)卷积码; 本实验以(7,4)分组码为例演示分组编码,卷积编码则在实验七中进行演示。 1.2 分组编码 1.2.1 编码M=(mk-1,mk-2,…,m1,m0)为单个码组中的信息码元; C=(cn-1,cn-2,…,c1,c0)为分组编码后的分组码; 分组编码的映射规则如下: 也就是说,编码过程为 k 个信息码的线性组合: 于是,我们就完成了将 k 维空间的信息码元映射到n维空间的编码过程。这多出来的 n-k 维元素将帮助我们在接收端进行纠错。 在二进制序列传输的过程的,显然不可避免的会出现差错,定义为: 错误图样 E=(en-1,en-2,…,e1,e0),发生错误的地方为1,其余为0; 则接收序列为 R = C + E 。根据神奇的线性代数知识,由于生成矩阵 G 是由 k 个线性无关的行向量组成,所以必然存在一个校验矩阵 H,使得 GHT=0,其中: 但是当然了,这个纠错能力是有限的,下面我们来具体的量化一下。 码距 定义为两个码组间对应位置不同的位数,也叫 汉明距离,记为 d。而所有码组间距离的最小值被称为 最小码距: 另外,按照定义计算最小码距很复杂。但是再次根据神奇的线性代数知识(二元线性分组码的封闭性),任意两个线性码组之和仍为许用码组,所以那两个码组间的距离就是另一个码组的 码重(码组中1的个数)。所以 码组中的最小码重=最小码距。 二、(7,4)汉明码编译码实例终于可以看实例了。 假如我们选择(7,4)汉明码,且令生成矩阵为: 将待编码序列分成长度为 4 的信息码元,根据生成矩阵计算出监督码元: 首先根据 1.2.2 的内容,由生成矩阵可以得到校验矩阵: 然后再取出改正后码组的前四位,就得到我们的信息码元了。完成译码。 三、代码展示及运行结果 3.1 (7,4)汉明码编码下面来验证上述编码实例,假设发送序列是M=[1 0 1 1 0 1 0 1 1 0],分组时不足 4 的整倍数将进行补零。 %% 实验六-汉明码编码过程 clear all clc %% 主函数 M = [1 0 1 1 0 1 0 1 1 0]; G = [1 0 0 0 1 1 0;... 0 1 0 0 1 0 1;... 0 0 1 0 0 1 1;... 0 0 0 1 1 1 1]; C = hamming(M,G) function C = hamming(M,G) [k,n] = size(G); % 输入序列补位 N = size(M,2); % 获得输入序列元素个数 r = k-rem(N,k); % 获得需要对输入序列进行补位的个数 M_add0 = [M,zeros(1,r)];% 补位 % 将输入信息序列进行分组 groups = ceil(length(M_add0)/k); % 获得分组个数 M_dis = reshape(M_add0,[k,groups]).'; %{ M_dis = zeros(groups,k); for i=1:groups M_dis(i,:) = M_add0(1,(1:k)*groups); end %} % 生成编码结果C C = mod(M_dis*G,2);% 生成结果别忘了对2取余 end得到结果为: 在上述编码的基础上添加译码子函数,完成对上述结果的译码。 %% 实验六-汉明码译码过程 clear all clc %% 主函数 % 生成分组编码C M = [1 0 1 1 0 1 0 1 1 0]; G = [1 0 0 0 1 1 0;... 0 1 0 0 1 0 1;... 0 0 1 0 0 1 1;... 0 0 0 1 1 1 1]; C = hamming(M,G); % 生成错误图样 % 第一行未发生错误、第二行发生一位、第三行发生两位错误 e = [0 0 0 0 0 0 0;... 1 0 0 1 0 0 0;... 0 1 0 0 0 0 0]; R = mod(C+e,2); C_result = decode(R,G) % 汉明译码 function C_result = decode(R,G) %{ 输入: 接收序列R 生成矩阵G 输出: 译码结果C_result %} % groups代表接收序列的编码组数 [groups,~] = size(R); % k代表每组中的信息码元大小,n代表一个组里面包含样本点数 [k,n] = size(G); % 根据G生成校验矩阵 H = [G(:,k+1:n).',eye(groups)]; % 生成伴随式S S = mod(R*(H.'),2); [S_row,S_column] = size(S); % 设置伴随式和错误图样的对应元胞矩阵 SE = {[0 0 0],[0 0 0 0 0 0 0];... [0 0 1],[0 0 0 0 0 0 1];... [0 1 0],[0 0 0 0 0 1 0];... [1 0 0],[0 0 0 0 1 0 0];... [1 1 1],[0 0 0 1 0 0 0];... [0 1 1],[0 0 1 0 0 0 0];... [1 0 1],[0 1 0 0 0 0 0];... [1 1 0],[1 0 0 0 0 0 0]}; % 找出计算出的伴随式所对应的错误图样,并进行纠正 C_result = zeros(S_row,n); [SE_row,SE_column] = size(SE); for m=1:S_row for n=1:SE_row if all(S(m,:) == cell2mat(SE(n,1))) C_result(m,:) = R(m,:)+cell2mat(SE(n,2)); C_result(m,:) = mod(C_result(m,:),2); end end end C_result = C_result(:,1:k); end % 生成汉明码 function C = hamming(M,G) [k,n] = size(G); % 输入序列补位 N = size(M,2); % 获得输入序列元素个数 r = mod(-rem(N,k),k); % 获得需要对输入序列进行补位的个数 M_add0 = [M,zeros(1,r)];% 补位 % 将输入信息序列进行分组 groups = ceil(length(M_add0)/k); % 获得分组个数 M_dis = reshape(M_add0,[k,groups]).'; %{ M_dis = zeros(groups,k); for i=1:groups M_dis(i,:) = M_add0(1,(1:k)*groups); end %} % 生成编码结果C C = mod(M_dis*G,2);% 生成结果别忘了对2取余 end译码结果为: 下面来点有意思的。在 AWGN 信道传输与 BPSK 调制的条件下,绘制未编码系统 与(7,4)汉明编码系统的误码率曲线。信噪比范围:0~5dB,系统流程图如下: 我输入就假设发送的原始码流有50w个符号,输出结果如下: 1.关于切割码流。编码函数只需要输入码流和生成矩阵,这很好。但是编码函数将各码组按行输出,想要传送还需要将其在主函数中 reshape 成码流;解码函数也需要提前将码流 reshape 成切割好的码流,这造成程序的移植性差。需要的小伙伴可以将 reshape 的过程放到子函数里,我就懒得改了。 2.自动计算(n,k)。这是优点,汉明码的编解码函数可以自动识别(n,k),用户只要输入自己的生成函数和码流即可(包括上面切割的过程也不需要调参),这增强了移植性。 代码原创,但因为原理编写参考到了实验课的指导书,假如有什么不对的地方,侵删。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |