香农编码的matlab实现

随机生成十个斑点吸收概率,使用香农编码对这些符号编码,代码如下
x=rand(1,10);
y=sum(x);
p=x/y;
p=sort(p,‘descend’);
n=length§;
h=0;
for i=1:n
h=-p(i)log2(p(i))+h;
end
pa=zeros(1,n);
for i=2:n
pa(i)=pa(i-1)+p(i-1);
end
z=-log2§;
k=zeros(1,n);
for j=1:n
k(j)=ceil(z(j));
end
km=max(k);
b=zeros(n,km);
for i=1:n
m=pa(i);
for j=1:k(i)
m=m
2;
b(i,j)=floor(m);
if m>=1
m=m-1;
end
end
end
ka=sum(p.*k);
r=h/ka;
disp§
for i=1:n
disp([num2str(p(i)),’: ',num2str(b(i,1:k(i)))]);
end
disp([‘编码速率:’,num2str®]);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、问题背景: 1949年香农在《有噪声时的通信》一文中提出了信道容量的概念和信道编码定理,为信道编码奠定了理论基础。无噪信道编码定理(又称香农第一定理)指出,码字的平均长度只能大于或等于信源的熵。有噪信道编码定理(又称香农第二定理)则是编码存在定理。它指出只要信息传输速率小于信道容量,就存在一类编码,使信息传输的错误概率可以任意小。随着计算技术和数字通信的发展,纠错编码和密码学得到迅速的发展。 2、课题分析: 运用matlab编写程序求解任给信源符号概率的香农编码。给定一组信源符号概率,通过所编写的程序对信源符号概率编码,求出此信源符号概率对应的香农编码。 3、编程方法: 据课本上的介绍编码香农码的方法。 首先,给定信源符号概率,要先判断信源符号概率是否满足概率分布,即各概率之和是否为1,如果不为1就没有继续进行编码的必要,虽然任可以正常编码,但编码失去了意义。 其次,对信源符号概率进行从小到大的排序,以便进行下一步。从第一步就知道信源符号的个数n,于是构造一个nx4的零矩阵D,以便储存接下来运算的结果。把排好序的信源符号概率以列的形式赋给D的第一列。 再次,做编码的第二步,求信源符号概率的累加概率(方法见程序),用来编写码字。 接着求各信源符号概率对应的自信息量,用于求解码长k。 然后,我们对刚求的自信息量对无穷方向取最小正整数,得到的最小正整数就是该信源符号所对应编码的码长k,有了码长,接下来就可以求解码字。 最后,对所求到的累加概率求其二进制,取其小数点后的数,所取位数由该信源符号对应的码长决定,所用的步骤结束,依次得到各信源符号的香农编码
算术编码是一种无损压缩算法,可以将任意长度的数据流压缩为一个较短的编码。而香农编码是一种基于概率的编码方法,可以使得出现概率较高的符号用较短的编码表示,出现概率较低的符号用较长的编码表示。 以下是算术编码和香农编码MATLAB实现代码: 算术编码: ```matlab function [code,prob] = arith_encode(source,prob) % 初始化概率表 if nargin < 2 prob = ones(1,256)/256; end % 计算累积概率 cumprob = cumsum(prob); % 计算区间范围 low = 0; range = 1; for i = 1:length(source) symbol = source(i); % 更新区间范围 newlow = low + range*cumprob(symbol); newrange = range*prob(symbol); % 缩小区间范围 low = newlow; range = newrange; end % 输出编码和最终概率表 code = floor(low*2^32); prob(source(end)) = prob(source(end)) + 1; prob = prob/sum(prob); end ``` 香农编码: ```matlab function [code,len] = shannon_encode(source) % 计算概率表 prob = histcounts(source,0:256)/length(source); % 计算累积概率 cumprob = cumsum(prob); % 初始化编码表 code = cell(1,256); for i = 1:256 % 计算编码 if prob(i) > 0 len = ceil(-log2(prob(i))); code{i} = sprintf('%%0%dd',len); code{i} = sprintf(code{i},dec2bin(cumprob(i)*2^len-1,len)); end end % 输出编码和编码长度 len = cellfun(@length,code); end ``` 这两个函数分别实现了算术编码和香农编码。你可以将需要压缩的数据传入这两个函数,得到对应的编码和编码长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值