%% SCMA simple Transceiverchain.m
clc;
clear;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Parameter settings %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PAR.FN=4; % variable nodes (VN), number of data layers
PAR.VN=6; % function nodes (FN), number of physical resources
PAR.d_f=3; % Each FN is connected to 3 VNs
PAR.d_v=2; % Each VN is connected to 2 FNs
PAR.M=4; % Number of codeword in each codebook
PAR.Data_length=4096; % Number of total data
PAR.N_iter=15; % Number of iterations in decoding
PAR.SNR_dB = 10;
PAR.CB=zeros(PAR.M,PAR.FN,PAR.VN); %Codebooks
PAR.CB(:,:,1)=[ 0,0,0,0;
-0.1815-0.1318i,-0.6351-0.4615i,0.6351+0.4615i,0.1815+0.1318i;
0,0,0,0;
0.7851,-0.2243,0.2243,-0.7851];
PAR.CB(:,:,2)=[ 0.7851,-0.2243,0.2243,-0.7851;
0,0,0,0;
-0.1815-0.1318i,-0.6351-0.4615i,0.6351+0.4615i,0.1815+0.1318i;
0,0,0,0];
PAR.CB(:,:,3)=[ -0.6351+0.4615i,0.1815-0.1318i,-0.1815+0.1318i,0.6351-0.4615i;
0.1392-0.1759i,0.4873-0.6156i,-0.4873+0.6156i,-0.1392+0.1759i;
0,0,0,0;
0,0,0,0];
PAR.CB(:,:,4)=[ 0,0,0,0;
0,0,0,0;
0.7851,-0.2243,0.2243,-0.7851;
-0.0055-0.2242i,-0.0193-0.7848i,0.0193+0.7848i,0.0055+0.2242i];
PAR.CB(:,:,5)=[ -0.0055-0.2242i,-0.0193-0.7848i,0.0193+0.7848i,0.0055+0.2242i;
0,0,0,0;
0,0,0,0;
-0.6351+0.4615i,0.1815-0.1318i,-0.1815+0.1318i,0.6351-0.4615i;];
PAR.CB(:,:,6)=[ 0,0,0,0;
0.7851,-0.2243,0.2243,-0.7851
0.1392-0.1759i,0.4873-0.6156i,-0.4873+0.6156i,-0.1392+0.1759i;
0,0,0,0];
%% Initialization
%data_source=ceil(PAR.M*rand(PAR.VN,PAR.Data_length)); %random data
%all data
c_t=1;
data_source=zeros(PAR.VN,PAR.Data_length);
for a=1:PAR.M
for b=1:PAR.M
for c=1:PAR.M
for d=1:PAR.M
for e=1:PAR.M
for f=1:PAR.M
data_source(:,c_t)=[a;b;c;d;e;f];
c_t=c_t+1;
end
end
end
end
end
end
%% SCMA Encoding
PRE_o=zeros(PAR.FN,PAR.Data_length);
for data_ind=1:PAR.Data_length
for v=1:PAR.VN
PRE_o(:,data_ind)=PRE_o(:,data_ind)+PAR.CB(:,data_source(v,data_ind),v);
end
end
%% Noise
sqrt_nvar = 1/sqrt(10^(0.1*PAR.SNR_dB));
noise = sqrt_nvar*(1/sqrt(2))*(randn(PAR.FN,PAR.Data_length)+j*randn(PAR.FN,PAR.Data_length));
PRE=PRE_o+noise;
%PRE=PRE_o;
%% SCMA Decoding
% calculate the index of neighbors for vn & fn
vn_nb=zeros(PAR.VN,PAR.d_v);
fn_nb=zeros(PAR.FN,PAR.d_f);
for i=1:PAR.VN
vn_nb(i,:)=(find(PAR.CB(:,1,i)~=0)');
end
for i=1:PAR.FN
[tmp,tmp1]=find(vn_nb==i);
fn_nb(i,:)=tmp';
end
fn_nb=sort(fn_nb,2);
err_sym_sum=0; %initial the total number of error symbol
for data_ind=1:PAR.Data_length
Fd=zeros(PAR.M,PAR.M,PAR.M,PAR.FN); %distance of all possible combinations (neighbor 1, neightor 2, neighbor 3, FN)
Ifv=zeros(PAR.M,PAR.FN,PAR.VN); %full index for easy searching (codeword of vn, fn ,vn )
Ivf=ones(PAR.M,PAR.VN,PAR.FN)/PAR.M; %full index for easy searching (codeword of vn, vn ,fn )
ap_old=ones(PAR.VN,PAR.M)/PAR.M; %A prior probability of codeword
ap_new=ones(PAR.VN,PAR.M)/PAR.M;
for f=1:PAR.FN
nb_CB=PAR.CB(:,:,fn_nb(f,:));
end
for f=1:PAR.FN
for i=1:PAR.M
for j=1:PAR.M
for k=1:PAR.M
Fd(i,j,k,f)=-(abs(PRE(f,data_ind)-PAR.CB(f,i,fn_nb(f,1))-PAR.CB(f,j,fn_nb(f,2))-PAR.CB(f,k,fn_nb(f,3))))^2;
end
end
end
end
%%%%%%%%%%%%%%
Pyx=exp(16*Fd);
%%%%%%%%%%%%%%
% Pyx=exp(Fd);
%% Iteration
for iter=1:PAR.N_iter
%% Ifv updates
for f=1:PAR.FN
for n=1:PAR.d_f
switch n
case 1
nb1=fn_nb(f,2);
nb2=fn_nb(f,3);
for i=1:PAR.M
sum_tmp=0;
for j=1:PAR.M
for k=1:PAR.M
sum_tmp=Pyx(i,j,k,f)*Ivf(j,nb1,f)*Ivf(k,nb2,f)+sum_tmp;
end
end
Ifv(i,f,fn_nb(f,n))=sum_tmp;
end
case 2
nb1=fn_nb(f,1);
nb2=fn_nb(f,3);
for j=1:PAR.M
sum_tmp=0;
for i=1:PAR.M
for k=1:PAR.M
sum_tmp=Pyx(i,j,k,f)*Ivf(i,nb1,f)*Ivf(k,nb2,f)+sum_tmp;
end
end
Ifv(j,f,fn_nb(f,n))=sum_tmp;
end
case 3
nb1=fn_nb(f,1);
nb2=fn_nb(f,2);
for k=1:PAR.M
sum_tmp=0;
for i=1:PAR.M
for j=1:PAR.M
sum_tmp=Pyx(i,j,k,f)*Ivf(i,nb1,f)*Ivf(j,nb2,f)+sum_tmp;
end
end
Ifv(k,f,fn_nb(f,n))=sum_tmp;
end
end
end
end
%% apv updates
for v=1:PAR.VN
ap_new(v,:)= ap_old(v,:).*(Ifv(:,vn_nb(v,1),v).*Ifv(:,vn_nb(v,2),v))';
ap_new(v,:)=ap_new(v,:)/sum(ap_new(v,:));
ap_old=ap_new;
end
%% Ivf updates
for v=1:PAR.VN
for n=1:PAR.d_v
switch n
case 1
for m=1:PAR.M
%Ivf(m,v,vn_nb(v,n))=Ifv(m,vn_nb(v,2),v)/sum(Ifv(:,vn_nb(v,2),v));
Ivf(m,v,vn_nb(v,n))=ap_new(v,m)*Ifv(m,vn_nb(v,2),v);
end
Ivf(:,v,vn_nb(v,n))=Ivf(:,v,vn_nb(v,n))/sum(Ivf(:,v,vn_nb(v,n)));
case 2
for m=1:PAR.M
%Ivf(m,v,vn_nb(v,n))=Ifv(m,vn_nb(v,1),v)/sum(Ifv(:,vn_nb(v,1),v));
Ivf(m,v,vn_nb(v,n))=ap_new(v,m)*Ifv(m,vn_nb(v,1),v);
end
Ivf(:,v,vn_nb(v,n))=Ivf(:,v,vn_nb(v,n))/sum(Ivf(:,v,vn_nb(v,n)));
end
end
end
end
Q=zeros(PAR.VN,PAR.M);
for v=1:PAR.VN
Q(v,:)=(Ifv(:,vn_nb(v,1),v).*Ifv(:,vn_nb(v,2),v))';
end
sub=sum(Q')';
sub=repmat(sub,1,4);
Q=Q./sub;
[tmp,R]=max(Q');
err=R'~=data_source(:,data_ind);
err_sym_sum=err_sym_sum+sum(err);
end
SER=err_sym_sum/PAR.VN/PAR.Data_length
评论0