循环码作为线性分组码的子类,自然可以用伴随式进行译码。另外,利用循环码的循环码特性,可以实现更为简单有效的捕错译码。
循环码的伴随式译码与线性分组码的伴随式译码思想相同,都包括根据接收码字 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(n−1)x(n−1)+e(n−2)x(n−2)+...+e(n−k)x(n−k)
校验部分的错误图样如下:
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(n−k−1)x(n=k−1)+e(n−k−2)x(n−k−2)+...+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 n−k+1。循环码作为线性分组码的一类,有条件限制且纠错能力 t < d t
根据循环码的性质,对于能够纠正 t 个错误的 (n,k) 循环码,经过 i 次循环移位后的接收码多项式 Ri(x) 对应的伴随式 Si 的重量小于等于 t 的充要条件是所有小于等于 t 个错误都集中再来移位后的码字的后 n-k 位。首先,如果错误已经集中在码字的低 n − k n-k n−k 位,则有:
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((d−1)/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,与假设条件不符。
我们以(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]);
至此准备工作已经完成,我们只需要输入信息序列,就可以得到编码结果
%%
%编码
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
我们下面以(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)];%因为是系统码,因此原信息码是编码的前4位
disp('原信息序列为:');
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]。正确码元的前四位就是原信息序列。