实验三-香农编码的MATLAB实现

信息论编码实验3~9连载,更多看专栏。

一、香农编码的原理

香农码严格意义上来说不是最佳码,与基于符号概率进行映射的哈夫曼编码不同的地方在于,香农码基于累积概率的二进制数进行编码。

编码步骤:

  1. 将概率分布列降序排序;
  2. 求出每一行所对应的累加概率 Pi
  3. 根据累加概率 Pi 计算该符号对应香农码的长度 Li
  4. 将累加概率 Pi 转换成二进制数,取其前 Li 位,即为该符号的香农码。

对于香农码的评价:
香农编码的效率不高,实用性不大,但对其他编码方法有很好的理论指导意义。一般情况下,按照香农编码方法编出来的码,其平均码长不是最短的,即不是紧致码(最佳码)。只有每一个符号的概率都是1/2的整数倍时,编码效率才能达到最高。

二、香农编码实例

以后有空再补充吧~

三、程序及流程图

下面是代码:

%% 实验三:香农编码仿真实验
clear all
clc
% 用户输入符号概率
p = input('请输入离散信源概率分布,例如[0.5,0.5]:\n');
N = length(p);
L = ceil(-log2(p));% 获得码长向量,元素表示每个符号所对应的码长

% 获得累加概率P及对应码字
[p_SortDescend,reflect] = sort(p,'descend');% 将概率从大到小进行排序
%注:reflect所表示的映射关系很重要
P = zeros(1,N);     % 初始化累加概率
CODE = strings(1,N); % 初始化对应码字(字符串形式)
for i=1:N           % i表示排序后第几个符号
    code = zeros(1,L(reflect(i)));% 初始化对应码字(数组形式)
    if i==1         % 定义第一个编码为0
        P(1)=0;
        CODE(reflect(i)) = num2str(code);
    else
        P(i) = sum(p_SortDescend(1,1:i-1)); % 获得累加概率
    end
    % 下面计算香农码(计算累加概率的二进制数,并取前Li位)
    p_count = P(i)*2;       % p_count用于逐步的计算累加概率的二进制数
    for m=1:L(reflect(i))   % m表示这个符号里第几个码字
       if p_count >= 1
            code(m) = 1;
            p_count = p_count-1;
       else
            code(m) = 0;
       end
       p_count = p_count*2;
    end
    % 将香农码赋值给对应的符号
    CODE(reflect(i)) = num2str(code);
end

H = sum(-p.*log2(p));   % 计算信源信息熵
L_ave = sum(L.*p);      % 计算平均码长
yita = H/L_ave;         % 计算编码效率

% 展示输出码字、平均码长和编码效率
fprintf('\n运行结果:\n');
disp(['信号符号: ',num2str(1:N)]);
disp(['对应概率: ',num2str(p)]);
fprintf('对应码字:');disp(CODE);
disp(['平均码长:',num2str(L_ave)]);
disp(['编码效率:',num2str(yita)]);

四、程序运行结果

下面假设输入[0.1,0.2,0.3,0.4]
在这里插入图片描述

五、程序自评价

怎么说呢,代码原理其实很简单,但是我一直对它的命令行窗口的输出耿耿于怀,这没有达到我理想的输出效果:

  1. 每一列对应元素都对齐;
  2. “对应码字”的输出不要加引号,并且可以密集排列;
  3. “对应码字”下面不要有换行。

经过我对disp、display、fprintf的反复试验,推测大概还是得输出到表格里,再读入才可能会达到理想效果,所以:嗯,就这样吧,挺好了,哈~

代码原创,但因为原理编写参考到了实验课的指导书,假如有什么不对的地方,侵删。

1、问题背景: 1949年香农在《有噪声时的通信》一文中提出了信道容量的概念和信道编码定理,为信道编码奠定了理论基础。无噪信道编码定理(又称香农第一定理)指出,码字的平均长度只能大于或等于信源的熵。有噪信道编码定理(又称香农第二定理)则是编码存在定理。它指出只要信息传输速率小于信道容量,就存在一类编码,使信息传输的错误概率可以任意小。随着计算技术和数字通信的发展,纠错编码和密码学得到迅速的发展。 2、课题分析: 运用matlab编写程序求解任给信源符号概率的香农编码。给定一组信源符号概率,通过所编写的程序对信源符号概率编码,求出此信源符号概率对应的香农编码。 3、编程方法: 据课本上的介绍编码香农码的方法。 首先,给定信源符号概率,要先判断信源符号概率是否满足概率分布,即各概率之和是否为1,如果不为1就没有继续进行编码的必要,虽然任可以正常编码,但编码失去了意义。 其次,对信源符号概率进行从小到大的排序,以便进行下一步。从第一步就知道信源符号的个数n,于是构造一个nx4的零矩阵D,以便储存接下来运算的结果。把排好序的信源符号概率以列的形式赋给D的第一列。 再次,做编码的第二步,求信源符号概率的累加概率(方法见程序),用来编写码字。 接着求各信源符号概率对应的自信息量,用于求解码长k。 然后,我们对刚求的自信息量对无穷方向取最小正整数,得到的最小正整数就是该信源符号所对应编码的码长k,有了码长,接下来就可以求解码字。 最后,对所求到的累加概率求其二进制,取其小数点后的数,所取位数由该信源符号对应的码长决定,所用的步骤结束,依次得到各信源符号的香农编码
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

虎慕

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

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

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

打赏作者

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

抵扣说明:

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

余额充值