信息论实验报告.docx
《信息论实验报告.docx》由会员分享,可在线阅读,更多相关《信息论实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
信息论实验报告
实验报告
实验名称
信息论信源信道编码
课程名称
信息论与编码
姓名
成绩
班级
学号
日期
2011/12/20
地点
综合实验楼
备注:
1.实验目的
本次信息论与编码的实验分信道编码及信源编码两个部分,其中信源编码包括Huffman码和Fano码,信道编码为Hamming码(74Hamming码)。
通过对三种编码的实现,了解Huffman码、Fano码和Hamming码编码对信息论的意义,了解相应的编码与译码原理,加深对编码的理解。
本次实验三个编码皆用MATLAB实现。
2.实验环境(软件、硬件及条件)
Windows2000/XP;
MATLAB6.xorabove;
3.实验方法
Huffman码:
哈夫曼编码是可变字长编码的一种。
该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。
哈夫曼编码的一般步骤如下:
(1)首先统计信源中各符号出现的概率,按符号出现的概率从大到小排序;
(2)把最小的两个概率相加合并成新的概率,与剩余的概率组成新的概率集合;
(3)对新的概率集合重新排序,再次把其中最小的两个概率相加,组成新的概率集合,如此重复进行,直到最后两个概率的和为1;
(4)分配码字。
码字分配从最后一步开始反向进行;
平均码长=sum(p.*ll);其中p为各码字出现概率,ll为编码后的码字长度;信源熵hh=sum(p.*(-log2(p)));;编码效率t=hh/l。
Fano码:
费诺编码属于概率匹配编码,但它不是最佳的编码方法。
不过有时也可以得到紧致码的性能。
信源符号以概率递减的次序排列进来,将排列好的信源符号划分为两大组,使第组的概率和近于相同,并各赋于一个二元码符号”0”和”1”.然后,将每一大组的信源符号再分成两组,使同一组的两个小组的概率和近于相同,并又分别赋予一个二元码符号.依次下去,直至每一个小组只剩下一个信源符号为止.这样,信源符号所对应的码符号序列则为编得的码字。
费诺码编码的一般步骤如下:
(1)将信源消息符号按其出现的概率大小依次排列排列:
。
(2)将依次排列的信源符号按概率值分为两大组,使两个组的概率之和近似相同,并且对各组赋予一个二进制码元“0”和“1”。
(3)将每一大组的信源符号再分成两组,使划分后的两个组的概率之和近似相同,并且对各组赋予一个二进制符号“0”和“1”。
以上两部分在程序中。
(4)如此重复,直到每个组只剩下一个信源符号为止。
在程序中本部分采用递归思想。
信源符号所对应的码字即为费诺编码。
Hamming码:
汉明码是用于数据传送,能检测所有一位和双位差错并纠正所有一位差错的二进制代码。
与其他的错误校验码类似,汉明码也利用了奇偶校验位的概念,通过在数据位后面增加一些比特,可以验证数据的有效性。
利用一个以上的校验位,汉明码不仅可以验证数据是否有效,还能在数据出错的情况下指明错误位置。
汉明码的编码一般步骤如下:
(1)码长n=7,信息元k=4,检验元r=n-k=3。
长为3的二元序列共有23=8个。
我们将其中7个非全零序列按列排成如下矩阵
H矩阵称为:
一致监督矩阵。
(2)设码字C=(c6c5c4c3c2c1c0),有:
H×CT=0T
其中:
0=(000),0T是0矢量的转置,即满足:
c3+c2+c1+c0=0
c5+c4+c1+c0=0
c6+c4+c2+c0=0
得出汉明码。
(3)汉明码译码,由H·
=H·
+H·
=
求出伴随式S
(4)给出生成矩阵
满足:
m·[G]=cG·
=0
(5)其译码纠错功能原理如下图所示,按照错误图样找到错误码字:
图1
4.实验分析
Huffman码:
运行结果:
>>pleaseinputanumber:
[0.20.50.3]
p=
0.20000.50000.3000
q=
0.20000.30000.5000
l=
132
a=
132
000
q=
0.50000.50001.0000
l=
123
a=
132
120
c=
0
01
c=
00
01
c=
000
01
c=
0001
01
c=
00011
01
h=
00
ll=
2
h=
00
1
ll=
21
h=
00
1
01
ll=
212
huffmancode:
h=
00
1
01
thehuffmaneffciency:
t=
0.9903
>>l=
1.5000%平均码长
>>hh=
1.4855%信源熵
平均码长十分接近信源熵,编码效率t=hh/l=0.9903。
Fano码:
运行结果:
>>inputtheA:
[0.150.10.20.050.20.20.1]
encoding=
0.200000-1.0000-1.0000-1.0000
0.200001.0000-1.0000-1.0000-1.0000
0.20001.000000-1.0000-1.0000
0.15001.000001.0000-1.0000-1.0000
0.10001.00001.00000-1.0000-1.0000
0.10001.00001.00001.00000-1.0000
0.05001.00001.00001.00001.0000-1.0000
%编码过程
A=
0.20000.20000.20000.15000.10000.10000.0500
%原码排序,与下面的编码相对应
CODE=
[0,1,100,101,110,1110,1111]
avlen=
2.3500%平均码长
Hamming码:
运行结果:
>>y=encoding([1101])
y=
1101010
%(7,4)汉明码
>>x=decoding(y)
x=
1101
%解码
>>x2=decoding([1001010])
x2=
1101
%模拟传输中第二个码字发生了错误,进行译码纠错
5.实验结论
本次对信源编码与信道编码在MATLAB上的实现,通过对网上资料的参考与自己的思考,给出了HUFFMAN码、FANO码、HAMMING码的matlab程序,更深入地了解了三种编码的编码原理及特征,收获颇丰。
附(相关代码):
1.
Huffman码:
p=input('pleaseinputanumber:
')
n=length(p);
fori=1:
n
ifp(i)<0
fprintf('\nTheprobabilitiesinhuffmancannotlessthan0!
\n');
p=input('pleaseinputanumber:
')%如果输入的概率数组中有小于0的值,则重新输入概率数组
end
end
ifabs(sum(p)-1)>0
fprintf('\nThesumoftheprobabilitiesinhuffmancanmorethan1!
\n');
p=input('pleaseinputanumber:
')%如果输入的概率数组总和大于1,则重新输入概率数组
end
q=p;
a=zeros(n-1,n);
fori=1:
n-1
[q,l]=sort(q)%对概率数组q进行从小至大的排序,并且用l数组返回一个数组,该数组表示概率数组q排序前的顺序编号
a(i,:
)=[l(1:
n-i+1),zeros(1,i-1)]
q=[q
(1)+q
(2),q(3:
n),1];
end
fori=1:
n-1
c(i,1:
n*n)=blanks(n*n);%生成一个n-1行n列,并且每个元素的的长度为n的空白数组,c矩阵用于进行huffman编码,并且在编码中与a矩阵有一定的对应关系
end
c(n-1,n)='0';
c(n-1,2*n)='1';%后两个概率,因此其值为0或1,在编码时设第n-1行的第一个空白字符为0,第二个空白字符1。
fori=2:
n-1
c(n-i,1:
n-1)=c(n-i+1,n*(find(a(n-i+1,:
)==1))-(n-2):
n*(find(a(n-i+1,:
)==1)))%矩阵c的第n-i的第一个元素的n-1的字符赋值为对应于a矩阵中第n-i+1行中值为1的位置在c矩阵中的编码值
c(n-i,n)='0'
c(n-i,n+1:
2*n-1)=c(n-i,1:
n-1)
c(n-i,2*n)='1'
forj=1:
i-1
c(n-i,(j+1)*n+1:
(j+2)*n)=c(n-i+1,n*(find(a(n-i+1,:
)==j+1)-1)+1:
n*find(a(n-i+1,:
)==j+1))%矩阵c中第n-i行第j+1列的值等于对应于a矩阵中第n-i+1行中值为j+1的前面一个元素的位置在c矩阵中的编码值
end
end
fori=1:
n
h(i,1:
n)=c(1,n*(find(a(1,:
)==i)-1)+1:
find(a(1,:
)==i)*n)%用h表示最后的huffman编码,矩阵h的第i行的元素对应于矩阵c的第一行的第i个元素
ll(i)=length(find(abs(h(i,:
))~=32))%计算每一个huffman编码的长度
end
l=sum(p.*ll);%计算平均码长
fprintf('\nhuffmancode:
\n');
h
hh=sum(p.*(-log2(p)));%计算信源熵
fprintf('\nthehuffmaneffciency:
\n');
t=hh/l%计算编码效率
2.
Fano码:
A=input('inputtheA:
');
A=fliplr(sort(A));%降序排列
[m,n]=size(A);
fori=1:
n
encoding(i,1)=A(i);%生成B的第1列
end
%生成B第2列的元素
a=sum(encoding(:
1))/2;
fork=1:
n-1
ifabs(sum(encoding(1:
k,1))-a)<=abs(sum(encoding(1:
k+1,1))-a)
break;
end
end
fori=1:
n%生成B第2列的元素
ifi<=k
encoding(i,2)=0;
else
encoding(i,2)=1;
end
end
%生成第一次编码的结果
CODE=encoding(:
2)';
CODE=sym(CODE);
%生成第3列及以后几列的各元素
j=3;
while(j~=0)
p=1;
while(p<=n)
x=encoding(p,j-1);
forq=p:
n
ifx==-1
break;
else
ifencoding(q,j-1)==x
y=1;
continue;
else
y=0;
break;
end
end
end
ify==1
q=q+1;
end
ifq==p|q-p==1
encoding(p,j)=-1;
else
ifq-p==2
encoding(p,j)=0;
CODE(p)=[char(CODE(p)),'0'];
encoding(q-1,j)=1;
CODE(q-1)=[char(CODE(q-1)),'1'];
else
a=sum(encoding(p:
q-1,1))/2;
fork=p:
q-2
ifabs(sum(encoding(p:
k,1))-a)<=abs(sum(encoding(p:
k+1,1))-a);
break;
end
end
fori=p:
q-1
ifi<=k
encoding(i,j)=0;
CODE(i)=[char(CODE(i)),'0'];
else
encoding(i,j)=1;
CODE(i)=[char(CODE(i)),'1'];
end
end
end
end
p=q;
end
C=encoding(:
j);
D=find(C==-1);
[e,f]=size(D);
ife==n
j=0;
else
j=j+1;
end
end
encoding
A
CODE
fori=1:
n
[u,v]=size(char(CODE(i)));
L(i)=v;
end
avlen=sum(L.*A)
3.
Hamming码:
function[y]=encoding(m)
n=length(m);
%n为原始码字的长度,即为4
%(7,4)汉明
y=[];
ifmod(n,4)~=0
n=n+4-mod(n,4)
m=[mzeros(1,4-mod(n,4))];
end
fori=1:
n/4
a=m((i-1)*4+1:
i*4);
forj=1:
4
b=mod(sum(a(1:
3)),2);
c=mod(sum([a(1:
2)a(4)]),2);
d=mod(a
(1)+a(3)+a(4),2);
end
y=[ya,b,c,d];
end;
function[y]=decoding(m)
H=[1110100;1101010;1011001];
s=mod(m*(H'),2);
ifsum(s==[000])==3
y=m(1:
4);
elseifsum(s==[001])==3
y=m(1:
4);
elseifsum(s==[010])==3
y=m(1:
4);
elseifsum(s==[100])==3
y=m(1:
4);
elseifsum(s==[011])==3
y=[m(1:
3)~m(4)];
elseifsum(s==[101])==3
y=[m(1:
2)~m(3)m(4)];
elseifsum(s==[110])==3
y=[m
(1)~m
(2)m(3:
4)];
elseifsum(s==[111])==3
y=[~m
(1)m(2:
4)];
end
end
end
end
end
end
end
end
参考文献:
《信息理论基础》北京航空航天大学出版社周荫清主编
《MATLAB程序设计与典型应用》电子工业出版社张德丰主编