代碼中已經有很多的解釋了,直接上源碼:
文件:香農編碼.m
%界面輸入的信源分佈[0.01,0.02,0.07,0.04,0.06,0.8] [0.2,0.18,0.17,0.15,0.19,0.1,0.01]
clc;
state = 1;%狀態碼,用於判斷用戶所輸入的信源概率是否符合要求
while state; %如果不符合要求一直做循環
pa=input('請輸入信源分佈:');
if min(pa)<0||max(pa)>1 %判斷信源概率值是否介於0到1之間
clc;
disp('概率值必須介於0到1之間,請重新輸入信源分佈');
elseif sum(pa)~=1 %判斷信源累加和是否爲1
clc;
disp(['您目前的概率累加和爲:',num2str(sum(pa)),' 注意:概率累加和必須等於1,請重新輸入信源分佈'])
else
k=length(pa); %計算信源符號個數
disp(['信源符號個數爲:',num2str(k)])
pa=sort(pa,'descend');
state = 0;
%for i=1:k-1 %for循環進行降序排列
%for n=i+1:k
%if (pa(i)<pa(n))
%t=pa(i);
%pa(i)=pa(n);
%pa(n)=t;
%end
%end
%end
end
end
disp(['信源分佈概率從大到小爲:',num2str(pa)])
y=0;%給y賦初值,用來求概率和
f=0;%給f賦初值,用來得到子程序最大循環次數
s=zeros(k,1); %對求和結果進行矩陣初始化
b=zeros(k,1); %對編碼位數矩陣初始化
w=zeros(k,1); %對二進制矩陣初始化
disp('初始概率 求和結果 編碼位數 最終編碼')
for m=1:k; %進行香農編碼
s(m)=y;
y=y+pa(m);
b(m)=ceil(-log2(pa(m)));%求得的自信息量向上取整,得到碼字長度
z=zeros(b(m),1); %對碼字矩陣初始化
f=max(b(m)); %把碼字最大長度賦給f,用於進行十進制轉二進制
w=dtob(s(m),f); %調用子程序將十進制轉換爲二進制
for r=1:b(m)
z(r)=w(r);
end
disp([' ',num2str(pa(m)),' ',num2str(s(m)),' ',num2str(b(m)),' ',num2str(z')])
end
L=0;
H=0;
for i=1:k %使用for循環進行信息熵、平均碼長求解
a(i)=-log2(pa(i)); %a(i)表示單個信源的自信息量
K(i)=ceil(a(i)); %K(i)表示對自信息量向上取整
R(i)=pa(i)*K(i);
L=L+R(i); %求平均碼長
c(i)=a(i)*pa(i);
H=H+c(i); %信息熵
end
Y=H/L; %用Y來表示編碼效率
disp(['信息熵H(X)=',num2str(H),'(bit/sign)']);
disp(['平均碼長K=',num2str(L),'(bit/sign)']);
disp(['編碼效率=',num2str(Y)]);
文件:dtob.m
function y=dtob(x,f)
for i=1:f
temp=x.*2;
if(temp<1)
y(i)=0;
x=temp;
else
x=temp-1;
y(i)=1;
end
end
備註:直接複製代碼到本地就可以運行!