MATLAB循环码编译码实验

循环码编译码实验

一、实验目的

1、掌握循环码编码原理和译码原理

2、练习使用Matlab编程实现循环码编码和译码

二、实验原理

循环码作为线性分组码的子类,自然可以用伴随式进行译码。另外,利用循环码的循环码特性,可以实现更为简单有效的捕错译码。

伴随式译码

循环码的伴随式译码与线性分组码的伴随式译码思想相同,都包括根据接收码字 R R R和校验矩阵 H 计算伴随式 S、根据伴随式 S 和编码规则估计错误图样 E 以及根据接收码字 R 和估计的错误图样 E E E得到译码码字 C C C等步骤。

捕错译码

捕错译码的基本思想是通过将接收码字中的错误集中并判断伴随式的重量实现译码,针对系统码的译码使用。
对于 ( n , k ) (n,k) (n,k)系统循环码(码字中的前 k 个码元为信息元),假设信息多项式为 m ( x ) m(x) m(x),发送码字多项式为 :
C ( x ) = m ( x ) x ( n + k ) + p ( x ) C(x)=m(x){{x}^{(n+k)}}+p(x) C(x)=m(x)x(n+k)+p(x)

其中,p(x) 为校验元对应的多项式,信道错误图样为:
E(x)=E_1 (x)+E_p (x)
其中,信息部分的错误图样如下:
E 1 ( x ) = e ( n − 1 ) x ( n − 1 ) + e ( n − 2 ) x ( n − 2 ) + . . . + e ( n − k ) x ( n − k ) {{E}_{1}}(x)={{e}_{(n-1)}}{{x}^{(n-1)}}+{{e}_{(n-2)}}{{x}^{(n-2)}}+...+{{e}_{(n-k)}}{{x}^{(n-k)}} E1(x)=e(n1)x(n1)+e(n2)x(n2)+...+e(nk)x(nk)

校验部分的错误图样如下:
E p ( x ) = e ( n − k − 1 ) x ( n = k − 1 ) + e ( n − k − 2 ) x ( n − k − 2 ) + . . . + e 1 x 1 + e 0 {{E}_{p}}(x)={{e}_{(n-k-1)}}{{x}^{(n=k-1)}}+{{e}_{(n-k-2)}}{{x}^{(n-k-2)}}+...+{{e}_{1}}{{x}^{1}}+{{e}_{0}} Ep(x)=e(nk1)x(n=k1)+e(nk2)x(nk2)+...+e1x1+e0

接收码多项式为 R(x),则伴随式多项式为:
S ( x ) ≡ R ( x ) ≡ E ( x ) ≡ ( E 1 ( x ) + E p ( x ) ) m o d [ g ( x ) ] S(x)≡R(x)≡E(x)≡(E_1 (x)+E_p (x))mod[g(x)] S(x)R(x)E(x)(E1(x)+Ep(x))mod[g(x)]
如果错误图样多项式 E(x) 的次数小于等于 n-k-1,则所有错误都集中在校验元上,此时
S ( x ) ≡ R ( x ) ≡ E ( x ) ≡ E p ( x ) m o d [ g ( x ) ] S(x)≡R(x)≡E(x)≡E_p (x)mod[g(x)] S(x)R(x)E(x)Ep(x)mod[g(x)]
而校验部分的错误图样的次数低于生成多项式的次数 n-k,因此伴随式 S 就是错误图样 E。从而纠错过程就简化为: C ^ = R + S \hat{C}=R+S C^=R+S
实际上,任一 (n,k,d) 线性分组码的最大最小距离等于 n − k + 1 n-k+1 nk+1。循环码作为线性分组码的一类,有条件限制且纠错能力 t < d t<d t<d。如果码字中出现的所有小于等于 t 个错误出现在连续的 n − k n-k nk 位,则要求循环码的参数满足信息组长度 k < n / t k<n/t k<n/t 或纠错能力 t < n / t t<n/t t<n/t
根据循环码的性质,对于能够纠正 t 个错误的 (n,k) 循环码,经过 i 次循环移位后的接收码多项式 Ri(x) 对应的伴随式 Si 的重量小于等于 t 的充要条件是所有小于等于 t 个错误都集中再来移位后的码字的后 n-k 位。首先,如果错误已经集中在码字的低 n − k n-k nk 位,则有:
S i ( x ) = E i p ( x ) S_i (x)=E_ip (x) Si(x)=Eip(x)
由于该 (n,k) 循环码能够纠正小于等于 t 个错误,如果错误图样是可纠正的,则必有:
w ( E ( x ) ) ≤ t w(E(x))≤t w(E(x))t
从而该错误图样经过 i 次循环移位后的错误图样重量保持不变。另一方面,如果错误图样的重量小于等于 t ,而错误没有集中,则经过 i 次循环移位后的错误图样的次数大于生成多项式的次数,从而有:
E i ( x ) − S i ( x ) = q ( x ) g ( x ) = C i ( x ) E_i (x)-S_i (x)=q(x)g(x)=C_i (x) Ei(x)Si(x)=q(x)g(x)=Ci(x)
由于 Ci(x) 是生成多项式的倍式,因此必是该 (n,k) 循环码的码字,因此其重量要大于等于码的最小距离,另外根据 t = f l o o r ( ( d − 1 ) / 2 ) t=floor((d-1)/2) t=floor((d1)/2)可得到:
w ( − S i ( x ) ) = w ( S i ( x ) ) ≥ t + 1 > t w(-{{S}_{i}}(x))=w({{S}_{i}}(x))\ge t+1>t w(Si(x))=w(Si(x))t+1>t
也即,如果错误没有集中在码字的底 n-k 位,则伴随式的重量必大于 t,与假设条件不符。

三、实验要求

1、编程实现码长n=15的各种循环码的编码、译码,给出相应的码生成多项式、(典型)监督矩阵和生成矩阵。

2、举例说明给定信息的编码结果(或者给出所有可能的编码结果)。

3、举例说明对收到码字的检错纠错结果。

四、实验内容

4.1 n=15的循环码的码生成多项式、(典型)监督矩阵和生成矩阵

我们以(15,7)循环码为例,首先调用cyclpoly函数生成所有x15-1的所有8次幂的因子

clear all;
close all;
n=15;
k=7;
p=cyclpoly(n,k,'all');  
%产生x15-1的所有三次幂的因子 Produce generator %polynomials for cyclic code

在这里插入图片描述

可以在workbench看到P的取值,分别是 x 8 + x 4 + x 2 + x + 1 {{\text{x}}^{8}}+{{x}^{4}}+{{x}^{2}}+x+1 x8+x4+x2+x+1 x 8 + x 7 + x 6 + x 4 + 1 {{\text{x}}^{8}}+{{x}^{7}}+{{x}^{6}}+{{x}^{4}}+1 x8+x7+x6+x4+1 x 8 + x 7 + x 5 + x 4 + x 3 + x + 1 {{\text{x}}^{8}}+{{x}^{7}}+{{x}^{5}}+{{x}^{4}}+{{x}^{3}}+x+1 x8+x7+x5+x4+x3+x+1。这些都是(15,7)循环码的生成多项式 g ( x ) g(x) g(x)

[H,G]=cyclgen(n,p(i,:),'system');

调用cyclgen生成(15,7) 系统循环码的生成矩阵G和校验矩阵 H。
在这里插入图片描述
可以发现MATLAB中 的定义和通信原理书上并不一样,它的单位矩阵在右侧。因此我们需要做旋转对称。

%cyclgen生成的G不是[IkQ]形式的,需要中心对称翻转,同理H
%中心旋转对称
H([1,8],:)=H([8,1],:);
H([2,7],:)=H([7,2],:);
H([3,6],:)=H([6,3],:);
H([4,5],:)=H([5,4],:);

H(:,[1,15])=H(:,[15,1]);
H(:,[2,14])=H(:,[14,2]);
H(:,[3,13])=H(:,[13,3]);
H(:,[4,12])=H(:,[12,4]);
H(:,[5,11])=H(:,[11,5]);
H(:,[6,10])=H(:,[10,6]);
H(:,[7,9])=H(:,[9,7]);

G([1,7],:)=G([7,1],:);
G([2,6],:)=G([6,2],:);
G([3,5],:)=G([5,3],:);
G(:,[1,15])=G(:,[15,1]);
G(:,[2,14])=G(:,[14,2]);
G(:,[3,13])=G(:,[13,3]);
G(:,[4,12])=G(:,[12,4]);
G(:,[5,11])=G(:,[11,5]);
G(:,[6,10])=G(:,[10,6]);
G(:,[7,9])=G(:,[9,7]);

4.2给定信息的编码结果

至此准备工作已经完成,我们只需要输入信息序列,就可以得到编码结果

%%
%编码
Msg=input('输入信息元序列:');
C=rem(Msg*G,2);
disp('编码后序列为:')
disp(C);

手动输入信息元序列,可以查看到编码结果
在这里插入图片描述
上述问题所有代码如下

clear all;
close all;
n=15;
k=7;
p=cyclpoly(n,k,'all');  %产生x7-1的所有三次幂的因子 Produce generator polynomials for cyclic code

for i=1:3

% [H1,H1]=cyclgen(n,p(1,:));%取第一个公因子x8++x4+x2+x+1,G为系统的,H为对应的校验阵
% [H2,G2]=cyclgen(n,p(2,:));%取第二个公因子x8++x7+x6+1,G为系统的,H为对应的校验阵
% [H3,G3]=cyclgen(n,p(3,:));%取第三个公因子x8+x7+x5+x4+x3+x+1,G为系统的,H为对应的校验阵

[H,G]=cyclgen(n,p(i,:),'system');

%%
%cyclgen生成的G不是[IkQ]形式的,需要中心对称翻转,同理H
%中心旋转对称
H([1,8],:)=H([8,1],:);
H([2,7],:)=H([7,2],:);
H([3,6],:)=H([6,3],:);
H([4,5],:)=H([5,4],:);

H(:,[1,15])=H(:,[15,1]);
H(:,[2,14])=H(:,[14,2]);
H(:,[3,13])=H(:,[13,3]);
H(:,[4,12])=H(:,[12,4]);
H(:,[5,11])=H(:,[11,5]);
H(:,[6,10])=H(:,[10,6]);
H(:,[7,9])=H(:,[9,7]);

G([1,7],:)=G([7,1],:);
G([2,6],:)=G([6,2],:);
G([3,5],:)=G([5,3],:);
G(:,[1,15])=G(:,[15,1]);
G(:,[2,14])=G(:,[14,2]);
G(:,[3,13])=G(:,[13,3]);
G(:,[4,12])=G(:,[12,4]);
G(:,[5,11])=G(:,[11,5]);
G(:,[6,10])=G(:,[10,6]);
G(:,[7,9])=G(:,[9,7]);
%%
%编码
Msg=input('输入信息元序列:');
C=rem(Msg*G,2);
disp('编码后序列为:')
disp(C);

end

4.3收到码字的检错纠错

我们下面以(7,4)循环码为例,验证通过差错图案对码字进行检错。

clear all;
close all;
n=7;
k=4;

%%
%编码
u=input('输入信息元序列:');
x=[zeros(1,n-k),1];
g=cyclpoly(n,k);
a=gfconv(x,u);

[q,m1]=gfdeconv(a,g);
a1=n-k-length(m1);
m=[m1,zeros(1,a1)];
code(1,:)=[u,m];
disp('编码后的序列为:')
disp(code)




%%
%利用校正子译码
Msg=input('输入接收到的序列:');
[q,s]=gfdeconv(fliplr(Msg),fliplr(g),2);%计算接受码字的校正子s
a=3-length(s);                         %补零长度,s长度不一定是n-k
s=[zeros(1,a),s];                      %长度为n-k的校正子



disp('纠错后的码字序列为:');
disp(code);
u=zeros(1,4);

%显示原信息序列
u=[code( :,1),code( :,2),code( :,3),code( :,4)];%因为是系统码,因此原信息码是编码的前4disp('原信息序列为:');
disp(u);

我们知道有 e ( x )   m o d   g ( x ) = r ′ ( x ) e(x)\bmod g(x)=r'(x) e(x)modg(x)=r(x)的关系,其中 e ( x ) e(x) e(x)是错误图样, r ′ ( x ) r'(x) r(x)是错误码元与 g ( x ) g(x) g(x)相除后的余项式,也是校验子。因而我们可以自己建表,通过查表修复码元。

%错误图样与校正子的关系
e0=[0 0 0 0 0 0 0];s0=[0 0 0];
e1=[0 0 0 0 0 0 1];s1=[0 0 1];
e2=[0 0 0 0 0 1 0];s2=[0 1 0];
e3=[0 0 0 0 1 0 0];s3=[1 0 0];
e4=[0 0 0 1 0 0 0];s4=[0 1 1];
e5=[0 0 1 0 0 0 0];s5=[1 1 0];
e6=[0 1 0 0 0 0 0];s6=[1 1 1];
e7=[1 0 0 0 0 0 0];s7=[1 0 1];

在这里为了简化计算,我们可以使用查表的方式,将校正子和对应的错误图样联系起来。

%%
%判决并由接受码字的校正子和对应的错误图样求码字
if s==s0
    code=Msg;
end

if s==s1
    code=gfadd(Msg,[0 0 0 0 0 0 1]);
end

if s==s2
    code=gfadd(Msg,[0 0 0 0 0 1 0]);
end

if s==s3
    code=gfadd(Msg,[0 0 0 0 1 0 0]);
end

if s==s4
    code=gfadd(Msg,[0 0 0 1 0 0 0]);
end

if s==s5
    code=gfadd(Msg,[0 0 1 0 0 0 0]);
end

if s==s6
    code=gfadd(Msg,[0 1 0 0 0 0 0]);
end

if s==s7
    code=gfadd(Msg,[1 0 0 0 0 0 0]);
end

通过MATLAB我们可以知道[1 1 1 0]的编码结果是[1 1 1 0 1 0 0],但是我们不妨输入错误了一位的码元序列[1 1 1 1 1 0 0]。通过校验子查表可以得到对应的错误图案,从而恢复正确的码元为[1 1 1 0 1 0 0]。正确码元的前四位就是原信息序列。
在这里插入图片描述

  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
循环码是一种常用的纠错码。其码过程涉及到生成多项式,循环移位和异或运算等步骤。下面是用MATLAB实现循环码码和解码的基本步骤: 1. 码过程: - 定义生成多项式g(x)。例如,根据循环码的参数(n, k, d),可以选择合适的生成多项式。 - 定义消息位向量M,长度为k,表示待码的消息。 - 定义初始码向量C,长度为n。 - 将M乘以x^(n-k)并存储在C的前k位。 - 对C的k到n-1位进行循环移位,并用g(x)进行异或运算,将结果存储回C的k到n-1位。 2. 译码过程: - 定义接收到的码向量R,长度为n,表示经过信道传输后接收到的码。 - 定义生成多项式g(x)。 - 定义初始解码向量E,长度为n。 - 对R进行循环移位,并用g(x)进行异或运算,将结果存储回E。 - 如果E的前k位全为0,则表示解码成功,消息位为E的后n-k位。否则,解码失败。 通过以上步骤,我们可以实现循环码码和解码。在MATLAB中,可以使用矩阵运算和位运算的方式实现。例如,可以使用MATLAB中的矩阵乘法运算符*进行消息位与x^(n-k)的乘法操作,使用MATLAB中的bitxor函数进行异或运算。 同时,MATLAB还提供了丰富的函数库,如polyval函数用于计算多项式的值,polygcd函数用于计算多项式的最大公约数等,可以方便地进行循环码码和解码操作。 需要注意的是,在码和解码的过程中,需要根据具体的循环码参数和生成多项式进行相应的实现,以确保码和解码正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WHS-_-2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值