Code covered by the BSD License

# Shannon-fano encoder

### Jamil Kasan (view profile)

13 May 2013 (Updated )

a shannonfano encoder with a row matrix input of occurrences/probab and outputs codewords&avelength

sfencoderkasan.m
```function[codex,T]=sfencoderkasan(ss)
%made by Jamil Kasan from Manila, Philippines
%input = row matrix of occurrences or probabilities e.g. ss=[1 3 4 5] or
%ss[0.4 0.3 0.2 0.1]
%outputs = string of codewords,average codeword length
ss=ss./sum(ss); %if occurrences are inputted, probabilities are gained
ss=sort(ss,'descend');  %the probabilities are sorted in descending order
siling=ceil(log2(1/ss(1))); %initial length is computed
sf=0;

fano=0;
%initializations for Pk
n=1;Hs=0; %initializations for entropy H(s)
for iii=1:length(ss)
Hs=Hs+ ss(iii)*log2(1/ss(iii)); %solving for entropy
end

for o=1:length(ss)-1
fano=fano+ss(o);
sf=[sf 0]+[zeros(1,o) fano]; %solving for Pk for every codeword
siling=[siling 0]+[zeros(1,o) ceil(log2(1/ss(o+1)))]; %solving for length every codeword
end

for r=1:length(sf)
esf=sf(r);

for p=1:siling(r)
esf=mod(esf,1)*2;
h(p)=esf-mod(esf,1); %converting Pk into a binary number
end
hh(r)=h(1)*10^(siling(r)-1); %initializtion for making the binary a whole number
for t=2:siling(r)
hh(r)=hh(r)+h(t)*10^(siling(r)-t);    %making the binary a whole number
end                                       %e.g. 0.1101 ==> 1101
end
c={'0','1'};
for i=1:length(hh)
u=1;                                      %converting the codes into a string
for t=siling(i):-1:1
f=floor(hh(i)/10^(t-1));               %1001 ==>1 (getting the first highest unit of a number)
hh(i)=mod(hh(i),10^(t-1));             %1001 ==>001(eliminating the first highest unit of a number)
if f==1
if u==1
d=c{2};                       %conversion part (num(1001) to str(1001))
else
d=[d c{2}];
end
else
if u==1
d=c{1};
else
d=[d c{1}];
end
end
codex{i,:}={d};
u=u+1;
end
end
tao=siling(1)*ss(1); %initialization for codeword length
for u=1:length(ss)-1 %computing for codeword length
tao=tao+siling(u+1)*ss(u+1);
end
T=tao/n; %computing for average codeword length
B=[flipud(rot90(ss)),flipud(rot90(siling)),flipud(rot90(sf))];
disp(['       s','        Li','        Pk'])
disp(B)
disp('Code')
disp(codex)
disp(['Hs = ',num2str(Hs)])
disp(['T = ',num2str(T),'bits/symbol'])
disp([num2str(Hs),' <= ',num2str(T),' <= ',num2str(Hs+1)])
```