t=a(i);
a(i)=a(n);
a(n)=t;
end
end
end
s=zeros(k,1);b=zeros(k,1);
form=1:
k
s(m)=y;
y=y+a(m);
b(m)=ceil(-log2(a(m)));
z=zeros(b(m),1);
x=s(m);
p=b2d10(x);
forr=1:
b(m)
z(r)=p(r);
end
disp('Êä³ö½á¹ûΪ£º')
disp('³öʸÅÂÊ'),disp(a(m))
disp('ÇóºÍ½á¹û'),disp(s(m))
disp('±àÂëλÊý'),disp(b(m))
disp('×îÖÕ±àÂë'),disp(z')
end
(2)functiony=b2d10(x)
fori=1:
8
temp=x.*2;
if(temp<1)
y(i)=0;
x=temp;
else
x=temp-1;
y(i)=1;
end
end
(3)p=[0.20.190.180.170.150.10.01];
sum=0;sum1=0;
fori=1:
7
a(i)=-log2(p(i));
K(i)=ceil(a(i));
R(i)=p(i)*K(i);
sum=sum+R(i);
c(i)=a(i)*p(i);
sum1=sum1+c(i);
end
K1=sum;
H=sum1;
Y=H/K1;
disp('ƽ¾ùÐÅÏ¢Á¿'),disp(H)
disp('ƽ¾ùÂ볤'),disp(K1)
disp('±àÂëЧÂÊ'),disp(Y)
六、实验结果
输出结果为:
出事概率0.2000,求和结果0,编码位数3,最终编码000
出事概率0.1900,求和结果0.2000,编码位数3,最终编码001
出事概率0.1800,求和结果0.3900,编码位数3,最终编码011
出事概率0.1700,求和结果0.5700,编码位数3,最终编码100
出事概率0.1500,求和结果0.7400,编码位数3,最终编码101
出事概率0.1000,求和结果0.8900,编码位数4,最终编码1110
出事概率0.0100,求和结果0.9900,编码位数7,最终编码1111110
编码效率:
平均信息量2.6087
平均码长3.1400
编码效率0.8308
七、实验总结
通过本次的实验,掌握了Shannon编码的实验原理以及编码过程。
Shannon编码中,对概率的排序是最基本的,如果没有将其按照从大到小的顺序排序,则经过MATLAB的程序运行后,将出现错误。
在运用MATLAB编程的过程中,调用了各种函数,实现了编程。
通过与队友的讨论,不但让我们更快的完成MATLAB编码,也深深体会到只有将大家的智慧融合起来,才能更快更好的解决难题。
实验四信道容量的迭代算法
一、实验目的
1、进一步熟悉信道容量的迭代算法;
2、学习如何将复杂的公式转化为程序;
3、熟悉程序设计语言的数值计算程序和调试技术。
二、实验原理
(1)初始化信源分布
(一般初始化为均匀分布),置迭代计数器k=0,设信道容量相对误差门限为
,
>0,可设;
(2)
(3)
(4)
(5)如果
,转向(7);
(6)置迭代序号
,转向
(2);
(7)输出
和
的结果;
(8)停止。
三、实验内容
1、已知:
信源符号个数r、新宿符号个数s、信道转移概率矩阵P;
2、输入:
任意的一个信道转移概率矩阵,信源符号个数、信宿符号个数和每一个具体的转移概率在运行时从键盘输入;
3、输出:
最佳信源分布P*,信道容量C。
四、实验环境
MicrosoftWindows7、
Matlab6.5
五、编码程序
aa.m文件:
clear;
r=input('输入信源个数:
');
s=input('输入信宿个数:
');
deta=input('输入信道容量的精度:
');
Q=rand(r,s);%创建m*n随机分布矩阵
A=sum(Q,2);
B=repmat(A,1,s);
disp('信源转移概率矩阵:
'),p=Q./B%信源转移概率矩阵
i=1:
1:
r;
q(i)=1/r;
disp('原始信源分布:
'),q
c=-10e-8;
C=repmat(q',1,s);
fork=1:
1:
100000
m=p.*C;%后验概率的分子部分
a=sum(m);%后验概率的分母部分
su1=repmat(a,r,1);
t=m./su1;%后验概率矩阵
D=exp(sum(p.*log(t),2));%信源分布的分子部分
su2=sum(D);%信源分布的分母部分
q=D/su2;%信源分布
C=repmat(q,1,s);
c(k+1)=log(sum(exp(sum(p.*log(t),2))))/log
(2);
kk=abs(c(k+1)-c(k))/c(k+1);
if(kk<=0.000001)
break;
end
end
disp('最大信道容量时的信源分布:
q='),disp(q')
disp('最大信道容量:
c='),disp(c(k+1))
六、实验结果结果
1)检验:
运行aa.m
输入信源的个数:
2
输入信宿的个数:
3
输入信道容量的精度:
0.000001
信宿转移概率矩阵:
p=0.50000.30000.2000
0.30000.50000.2000
原始信源分布:
q=0.50000.5000
最佳信源分布:
q=0.50000.5000
最大信道容量:
c=0.0365
2)计算信源个数为3,信宿个数为5的信道容量:
运行aa.m
输入信源的个数:
3
输入信宿的个数:
5
输入信道容量的精度:
0.000001
信宿转移概率矩阵:
p=0.04840.13850.30580.28450.2227
0.21040.24710.10770.37620.0585
0.34300.08000.18080.34280.0534
原始信源分布:
q=0.33330.33330.3333
最佳信源分布:
q=0.46910.17940.3515
最大信道容量:
c=0.1559
七、实验总结
通过实验,我们对信道容量的理解更加深刻了。
信道容量是指信道能无错误传送的最大信息率。
信道的输入、输出都取值于离散符号集,且都用一个随机变量来表示的信道就是离散单符号信道。
由于信道中存在干扰,因此输入符号在传输中将会产生错误,这种信道干扰对传输的影响可用传递概率来描述。
为了评价实际信道的利用率,应具体计算已给信道的容量。
这是一个求最大值的问题。
由于互信息对输入符号概率而言是凸函数,其极值将为最大值,因此这也就是求极值的问题。
对于离散信道,P(x)是一组数,满足非负性和归一性等条件,可用拉格朗日乘子法求得条件极值。
对于连续信道,P(x)是一函数,须用变分法求条件极值。
实验过程中,我们虽然也遇到了很多困难,但也正是因为如此,我们才能发现自己基础的薄弱点,学的更有方向。
对于编程方面,我们也有了很大的提升。
实验五率失真函数
一、实验目的
验证率失真函数的极值特性,理解相关参数的变化对率失真函数的影响。
二、实验原理
(1)输入S,d的初始值、条件概率、输出分布等值;
(2)计算输出分布
;
(3)进入迭代,标志为0或者误差大于指定eps则迭代,否则退出迭代;
(4)计算一个互信息
;
(5)计算一个条件概率分布
;
(6)重算一次(4),并计算
;
(7)重算(3)-(7)步骤,直到退出迭代;
三、实验环境
MicrosoftWindows7、
VisualStudio2005profession
四、编码程序
#include
#include
#include
usingnamespacestd;
//Definesomeglobalvar
constintM=10;//M元信源
constdoubleS=-50;//迭代算法中的中间量,S越小,允许最大失真度D越小,当S很小时(例如-100),R(D)=H(X)
staticintd[M][M];//失真函数
staticdoubleq[M],Pji[M][M];//输出分布和条件概率分布
staticdoublePi[M]={0.4,0.1,0.25,0.1,0.05,0.05,0.01,0.02,0.005,0.015};//初始化信源的概率分布
constintsystemDefine=2;//定义进制(默认为2进制,结果为bit,为e时,结果为nat)
constdoubleeps=1e-8;//允许误差
//计算输出分布(qj)
voidcalcOutDistribution()
{
inti,j;
for(j=0;j{
q[j]=0;
for(i=0;i{
q[j]+=Pi[i]*Pji[i][j];
}
}
}
//计算条件概率分布pji
voidcalcProbabilityDistribution()
{
inti,j,k;
doubletemp=0;
for(i=0;i{
temp=0;
for(k=0;k{
temp=temp+q[k]*exp(S*d[i][k]);
}
for(j=0;j{
//设定一个初始的条件概率分布
Pji[i][j]=q[j]*exp(S*d[i][j])/temp;
}
}
}
//取得R(r,r)=I(qj;Pji)【实际上就是根据互信息量公式求互信息】
doublegetSelfInformation()
{
inti,j;
doubleI=0;
for(i=0;i{
for(j=0;j{
I+=Pi[i]*Pji[i][j]*log(Pji[i][j]/q[j])/log(systemDefine);//求互信息量
}
}
returnI;
}
intmain(intargc,char*argv[])
{
doubleprobabilityCount=0.0;//概率和
for(intk=0;k{
probabilityCount+=Pi[k];
}
//和不为1,说明概率有错误
if(fabs(probabilityCount-1.0)>eps)
{
cout<<"概率和不为1,程序异常退出!
"<