《信息处理与编码》结课大作业
学号:
班级:
姓名:
成绩:
香农编码的 matlab 语言实现
1、问题背景:
1949 年香农在《有噪声时的通信》一文中提出了信道容量的概念和信道编码
定理,为信道编码奠定了理论基础。无噪信道编码定理(又称香农第一定理)指出,
码字的平均长度只能大于或等于信源的熵。有噪信道编码定理(又称香农第二定理)
则是编码存在定理。它指出只要信息传输速率小于信道容量,就存在一类编码,使信
息传输的错误概率可以任意小。随着计算技术和数字通信的发展,纠错编码和密码学
得到迅速的发展。
2、课题分析:
运用 matlab 编写程序求解任给信源符号概率的香农编码。给定一组信源符号概
率,通过所编写的程序对信源符号概率编码,求出此信源符号概率对应的香农编码。
3、编程方法:
据课本上的介绍编码香农码的方法。
首先,给定信源符号概率,要先判断信源符号概率是否满足概率分布,即各概率
之和是否为 1,如果不为 1 就没有继续进行编码的必要,虽然任可以正常编码,但编
码失去了意义。
其次,对信源符号概率进行从小到大的排序,以便进行下一步。从第一步就知道
信源符号的个数 n,于是构造一个 nx4 的零矩阵 D,以便储存接下来运算的结果。把
排好序的信源符号概率以列的形式赋给 D 的第一列。
再次,做编码的第二步,求信源符号概率的累加概率(方法见程序),用来编写
码字。
接着求各信源符号概率对应的自信息量,用于求解码长 k。
然后,我们对刚求的自信息量对无穷方向取最小正整数,得到的最小正整数就是
该信源符号所对应编码的码长 k,有了码长,接下来就可以求解码字。
最后,对所求到的累加概率求其二进制,取其小数点后的数,所取位数由该信源
符号对应的码长决定,所用的步骤结束,依次得到各信源符号的香农编码。
4、程序展现:
clc;
clear;
A=[0.4,0.3,0.1,0.09,0.07,0.04];
A=fliplr(sort(A));%降序排列
[m,n]=size(A);
for i=1:n
B(i,1)=A(i);%生成 B 的第 1 列
end
%生成 B 第 2 列的元素
a=sum(B(:,1))/2;
for k=1:n-1
if abs(sum(B(1:k,1))-a)<=abs(sum(B(1:k+1,1))-a)
break;
end
end
for i=1:n%生成 B 第 2 列的元素
if i<=k
B(i,2)=0;
B(i,2)=1;
else
end
end
%生成第一次编码的结果
END=B(:,2)';
END=sym(END);
%生成第 3 列及以后几列的各元素
j=3;
while (j~=0)
p=1;
while(p<=n)
x=B(p,j-1);
for q=p:n
if x==-1
break;
else
if B(q,j-1)==x
y=1;
continue;
else
end
y=0;
break;
end
end
if y==1
q=q+1;
end
if q==p|q-p==1
B(p,j)=-1;
else
if q-p==2
B(p,j)=0;
END(p)=[char(END(p)),'0'];
B(q-1,j)=1;
END(q-1)=[char(END(q-1)),'1'];
else
a=sum(B(p:q-1,1))/2;
for k=p:q-2
if abs(sum(B(p:k,1))-a)<=abs(sum(B(p:k+1,1))-a);
break;
end
end
for i=p:q-1
if i<=k
B(i,j)=0;
END(i)=[char(END(i)),'0'];
B(i,j)=1;
END(i)=[char(END(i)),'1'];
else
end
end
end
end
p=q;
end
C=B(:,j);
D=find(C==-1);
[e,f]=size(D);
if e==n
j=0;
j=j+1;
else
end
end
B
A
END
for i=1:n
[u,v]=size(char(END(i)));
L(i)=v;
end
avlen=sum(L.*A)
运行结果:
B =
0.4000
0.3000
0.1000
0.0900
0.0700
0.0400
0
1.0000
1.0000
1.0000
1.0000
1.0000
-1.0000
0
1.0000
1.0000
1.0000
1.0000
-1.0000
-1.0000
0
0
1.0000
1.0000
-1.0000
-1.0000
0
1.0000
0
1.0000
-1.0000
-1.0000
-1.0000
-1.0000
-1.0000
-1.0000
A =
0.4000
0.3000
0.1000
0.0900
0.0700
0.0400
END =
[
0,
10, 1100, 1101, 1110, 1111]
avlen =
2.2000
>>
5、结果分析:
此程序是据课本香农编码叙述编写,编写过程简洁,能够看到每个过程的结果,
经过多次循环和函数调用直接求解码字。在运行开始先确定要求解的信源符号个数,
输入概率时循环控制输入的次数,接下来判断概率是否符合要求。
香农编码是码符号概率大的用短码表示,概率小的是用长码表示,程序中对概率
排序,最后求得的码字就依次与排序后的符号概率对应。此程序缺点是,第一个码字
都是以 0 开始,因为对累加概率求二进制后,小数点后的数都是 0,取几位由码长确
定,而香农编码是不唯一的,如果手动编码就不存在这样的问题。后面求得的编码没
有下标就需要注意是与上面排序后的信源符号对应。