clc; close all;clear all

%% OFDM
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata = 108; %(256/4 = 64) number of subcarriers used for data transmission
 Nsym = 50000; % number of OFDM blocks

M = 4; % M-ary signal constellation (e.g., M-QAM)

% OFDM modulation
QAM_bit_Tx = floor(rand(1,Ndata*Nsym*log2(M))*2);
QAM_bit_Tx_para = vec2mat(QAM_bit_Tx,log2(M));

% MQAM encoding
QAM_decimal_tx = bi2de(QAM_bit_Tx_para,'left-msb');
QAM_stardata_tx = qammod(QAM_decimal_tx,M,0,'gray').';
Tx = vec2mat(QAM_stardata_tx,Ndata);

% IFFT using Hermitian symmetry(HS)
Tx_conj = fliplr(conj(Tx));
IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Tx; % x1 and xN/2+1 are set to 0
IFFT_input(:,NF-Ndata+1:NF) = Tx_conj;
IFFT_output_OFDM = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
%
for i = 1:Nsym
    P_OFDM(i) = max(IFFT_output_OFDM(i,:).^2);
    P_av_OFDM(i) = mean(IFFT_output_OFDM(i,:).^2);
    PAPR_OFDM(i) = P_OFDM(i)/P_av_OFDM(i);
    PAPR_dB_OFDM(i) = 10*log10(PAPR_OFDM(i));
end

[f_OFDM,x_OFDM] = ecdf(PAPR_dB_OFDM);
ff_OFDM = 1 - f_OFDM;




%% OFDM_DFT
 NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata = 108; %(256/4 = 64) number of subcarriers used for data transmission
Nsym =50000; % number of OFDM blocks

 M = 4; % M-ary signal constellation (e.g., M-QAM)


% OFDM modulation
QAM_bit_Tx = floor(rand(1,Ndata*Nsym*log2(M))*2);
QAM_bit_Tx_para = vec2mat(QAM_bit_Tx,log2(M));

% MQAM encoding
QAM_decimal_tx = bi2de(QAM_bit_Tx_para,'left-msb');
QAM_stardata_tx = qammod(QAM_decimal_tx,M,0,'gray').';
Subblock_tx=QAM_stardata_tx;

Tx = (reshape(Subblock_tx.',Ndata,Nsym)).';

% DFT spreading (localized)
DFT_input = Tx;
DFT_output = fft(DFT_input,Ndata,2);

% IFFT with HS
Tx_DFT = DFT_output;
Tx_DFT_conj = fliplr(conj(Tx_DFT));

IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Tx_DFT; % x1 and xN/2+1 are set to 0
IFFT_input(:,NF-Ndata+1:NF) = Tx_DFT_conj;
IFFT_output_OFDM_DFT = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
%
for i = 1:Nsym
    P_OFDM_DFT(i) = max(IFFT_output_OFDM_DFT(i,:).^2);
    P_av_OFDM_DFT(i) = mean(IFFT_output_OFDM_DFT(i,:).^2);
    PAPR_OFDM_DFT(i) = P_OFDM_DFT(i)/P_av_OFDM_DFT(i);
    PAPR_dB_OFDM_DFT(i) = 10*log10(PAPR_OFDM_DFT(i));
end

[f_OFDM_DFT,x_OFDM_DFT] = ecdf(PAPR_dB_OFDM_DFT);
ff_OFDM_DFT = 1 - f_OFDM_DFT;




%% 41
%% 4QAM_41
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata =118; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K = 1; % K out of N subcarriers in each subblock are active

M =4; % M-ary signal constellation (e.g., M-QAM)


%% OFDM-QIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc =K*log2(M); % number of bits carried by constellations on active subcarriers 
b = 2*bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');
% scatterplot(Con_tx);
% I/Q
Con_tx_Re=real(Con_tx);
Con_tx_Im=imag(Con_tx);

Con_tx_norm_Re = Con_tx_Re;%/sqrt(Ps);
Con_tx_para_Re = vec2mat(Con_tx_norm_Re,K);
Con_tx_norm_Im = Con_tx_Im;%/sqrt(Ps);
Con_tx_para_Im = vec2mat(Con_tx_norm_Im,K);

% Index symbol
Bit_index_tx1 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para1 = vec2mat(Bit_index_tx1,bi);

Bit_index_tx2 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para2 = vec2mat(Bit_index_tx2,bi);

% Subblock creation
Subblock_tx1 = Mapper_LLR_QIM(Bit_index_tx_para1,Con_tx_para_Re,N,K,G,Nsym);

Subblock_tx2 = Mapper_LLR_QIM(Bit_index_tx_para2,Con_tx_para_Im,N,K,G,Nsym);
% OFDM block creation

Subblock_tx=Subblock_tx1+1j*Subblock_tx2;
% scatterplot(Subblock_tx(:,1));

Data_tx = (reshape(Subblock_tx.',Ndata,Nsym)).';
 % scatterplot(Data_tx(:,24));

Data_tx_conj = fliplr(conj(Data_tx));

% IFFT with HS
IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Data_tx;
IFFT_input(:,NF-Ndata+1:NF) = Data_tx_conj;
IFFT_output4QAM_41 = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR

for i = 1:Nsym
    P4QAM_41(i) = max(IFFT_output4QAM_41(i,:).^2);
    P_av4QAM_41(i) = mean(IFFT_output4QAM_41(i,:).^2);
    PAPR4QAM_41(i) = P4QAM_41(i)/P_av4QAM_41(i);
    PAPR_dB4QAM_41(i) = 10*log10(PAPR4QAM_41(i));
end

[f4QAM_41,x4QAM_41] = ecdf(PAPR_dB4QAM_41);
ff4QAM_41 = 1 - f4QAM_41;

%% 4QAM_41DFT
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata = 118; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K = 1; % K out of N subcarriers in each subblock are active

M =4; % M-ary signal constellation (e.g., M-QAM)

% OFDM-QIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc =K*log2(M); % number of bits carried by constellations on active subcarriers 
b = 2*bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');
% scatterplot(Con_tx);
% I/Q
Con_tx_Re=real(Con_tx);
Con_tx_Im=imag(Con_tx);

Con_tx_norm_Re = Con_tx_Re;%/sqrt(Ps);
Con_tx_para_Re = vec2mat(Con_tx_norm_Re,K);
Con_tx_norm_Im = Con_tx_Im;%/sqrt(Ps);
Con_tx_para_Im = vec2mat(Con_tx_norm_Im,K);

% Index symbol
Bit_index_tx1 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para1 = vec2mat(Bit_index_tx1,bi);

Bit_index_tx2 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para2 = vec2mat(Bit_index_tx2,bi);

% Subblock creation
Subblock_tx1 = Mapper_LLR_QIM(Bit_index_tx_para1,Con_tx_para_Re,N,K,G,Nsym);

Subblock_tx2 = Mapper_LLR_QIM(Bit_index_tx_para2,Con_tx_para_Im,N,K,G,Nsym);
% OFDM block creation

Subblock_tx=Subblock_tx1+1j*Subblock_tx2;
% scatterplot(Subblock_tx(:,1));

% OFDM block creation
Tx = (reshape(Subblock_tx.',Ndata,Nsym)).';

% DFT spreading (localized)
DFT_input = Tx;
DFT_output = fft(DFT_input,Ndata,2);

% IFFT with HS
Tx_DFT = DFT_output;
Tx_DFT_conj = fliplr(conj(Tx_DFT));

IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Tx_DFT; % x1 and xN/2+1 are set to 0
IFFT_input(:,NF-Ndata+1:NF) = Tx_DFT_conj;
IFFT_output4QAM_41DFT = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
for i = 1:Nsym
    P4QAM_41DFT(i) = max(IFFT_output4QAM_41DFT(i,:).^2);
    P_av4QAM_41DFT(i) = mean(IFFT_output4QAM_41DFT(i,:).^2);
    PAPR4QAM_41DFT(i) = P4QAM_41DFT(i)/P_av4QAM_41DFT(i);
    PAPR_dB4QAM_41DFT(i) = 10*log10(PAPR4QAM_41DFT(i));
end

[f4QAM_41DFT,x4QAM_41DFT] = ecdf(PAPR_dB4QAM_41DFT);
ff4QAM_41DFT = 1 - f4QAM_41DFT;



%% SMIM_LLR_16QAM_41
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata =118; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K =1; % K out of N subcarriers in each subblock are active

M = 16; % M-ary signal constellation (e.g., M-QAM)

% OFDM-SIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc = K*log2(M); % number of bits carried by constellations on active subcarriers 
b = bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');

Con_tx_norm = Con_tx;%/sqrt(Ps);
Con_tx_para = vec2mat(Con_tx_norm,K);
% scatterplot(reshape(Con_tx,1,size(Con_tx,1)*size(Con_tx,2)));

% Index symbol
Bit_index_tx = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para = vec2mat(Bit_index_tx,bi);

% Subblock creation
Subblock_tx = Mapper_LLR(Bit_index_tx_para,Con_tx_para,N,K,G,Nsym);
    % scatterplot(Subblock_tx(:,2));
% OFDM block creation
Data_tx = (reshape(Subblock_tx.',Ndata,Nsym)).';
 % scatterplot(Data_tx(:,24));

Data_tx_conj = fliplr(conj(Data_tx));

% IFFT with HS
IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Data_tx;
IFFT_input(:,NF-Ndata+1:NF) = Data_tx_conj;
IFFT_output16QAM_41 = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
%
for i = 1:Nsym
    P16QAM_41(i) = max(IFFT_output16QAM_41(i,:).^2);
    P_av16QAM_41(i) = mean(IFFT_output16QAM_41(i,:).^2);
    PAPR16QAM_41(i) = P16QAM_41(i)/P_av16QAM_41(i);
    PAPR_dB16QAM_41(i) = 10*log10(PAPR16QAM_41(i));
end

[f16QAM_41,x16QAM_41] = ecdf(PAPR_dB16QAM_41);
ff16QAM_41 = 1 - f16QAM_41;

%% SMIM_LLR_16QAM_41DFT
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata =118; % number of subcarriers used for data transmission
Nsym =50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K =1; % K out of N subcarriers in each subblock are active

M = 16; % M-ary signal constellation (e.g., M-QAM)

%% OFDM-SIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc = K*log2(M); % number of bits carried by constellations on active subcarriers 
b = bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');

Con_tx_norm = Con_tx;%/sqrt(Ps);
Con_tx_para = vec2mat(Con_tx_norm,K);
% scatterplot(reshape(Con_tx,1,size(Con_tx,1)*size(Con_tx,2)));

% Index symbol
Bit_index_tx = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para = vec2mat(Bit_index_tx,bi);

% Subblock creation
Subblock_tx = Mapper_LLR(Bit_index_tx_para,Con_tx_para,N,K,G,Nsym);
    % scatterplot(Subblock_tx(:,2));
% OFDM block creation
% OFDM block creation
Tx = (reshape(Subblock_tx.',Ndata,Nsym)).';

% DFT spreading (localized)
DFT_input = Tx;
DFT_output = fft(DFT_input,Ndata,2);

% IFFT with HS
Tx_DFT = DFT_output;
Tx_DFT_conj = fliplr(conj(Tx_DFT));

IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Tx_DFT; % x1 and xN/2+1 are set to 0
IFFT_input(:,NF-Ndata+1:NF) = Tx_DFT_conj;
IFFT_output16QAM_41DFT = ifft(IFFT_input,NF,2); % oversample by lines


% PAPR
%
for i = 1:Nsym
    P16QAM_41DFT(i) = max(IFFT_output16QAM_41DFT(i,:).^2);
    P_av16QAM_41DFT(i) = mean(IFFT_output16QAM_41DFT(i,:).^2);
    PAPR16QAM_41DFT(i) = P16QAM_41DFT(i)/P_av16QAM_41DFT(i);
    PAPR_dB16QAM_41DFT(i) = 10*log10(PAPR16QAM_41DFT(i));
end

[f16QAM_41DFT,x16QAM_41DFT] = ecdf(PAPR_dB16QAM_41DFT);
ff16QAM_41DFT = 1 - f16QAM_41DFT;



%% 42
%% 4QAM_42
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata = 108; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K = 2; % K out of N subcarriers in each subblock are active

M =4; % M-ary signal constellation (e.g., M-QAM)


% OFDM-QIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc =K*log2(M); % number of bits carried by constellations on active subcarriers 
b = 2*bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');
% scatterplot(Con_tx);
% I/Q
Con_tx_Re=real(Con_tx);
Con_tx_Im=imag(Con_tx);

Con_tx_norm_Re = Con_tx_Re;%/sqrt(Ps);
Con_tx_para_Re = vec2mat(Con_tx_norm_Re,K);
Con_tx_norm_Im = Con_tx_Im;%/sqrt(Ps);
Con_tx_para_Im = vec2mat(Con_tx_norm_Im,K);

% Index symbol
Bit_index_tx1 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para1 = vec2mat(Bit_index_tx1,bi);

Bit_index_tx2 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para2 = vec2mat(Bit_index_tx2,bi);

% Subblock creation
Subblock_tx1 = Mapper_LLR_QIM(Bit_index_tx_para1,Con_tx_para_Re,N,K,G,Nsym);

Subblock_tx2 = Mapper_LLR_QIM(Bit_index_tx_para2,Con_tx_para_Im,N,K,G,Nsym);
% OFDM block creation

Subblock_tx=Subblock_tx1+1j*Subblock_tx2;
% scatterplot(Subblock_tx(:,1));

Data_tx = (reshape(Subblock_tx.',Ndata,Nsym)).';
 % scatterplot(Data_tx(:,24));

Data_tx_conj = fliplr(conj(Data_tx));

% IFFT with HS
IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Data_tx;
IFFT_input(:,NF-Ndata+1:NF) = Data_tx_conj;
IFFT_output4QAM_42 = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
for i = 1:Nsym
    P4QAM_42(i) = max(IFFT_output4QAM_42(i,:).^2);
    P_av4QAM_42(i) = mean(IFFT_output4QAM_42(i,:).^2);
    PAPR4QAM_42(i) = P4QAM_42(i)/P_av4QAM_42(i);
    PAPR_dB4QAM_42(i) = 10*log10(PAPR4QAM_42(i));
end

[f4QAM_42,x4QAM_42] = ecdf(PAPR_dB4QAM_42);
ff4QAM_42 = 1 - f4QAM_42;

%% 4QAM_42DFT
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata =108; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K = 2; % K out of N subcarriers in each subblock are active

M =4; % M-ary signal constellation (e.g., M-QAM)

% OFDM-QIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc =K*log2(M); % number of bits carried by constellations on active subcarriers 
b = 2*bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');
% scatterplot(Con_tx);
% I/Q
Con_tx_Re=real(Con_tx);
Con_tx_Im=imag(Con_tx);

Con_tx_norm_Re = Con_tx_Re;%/sqrt(Ps);
Con_tx_para_Re = vec2mat(Con_tx_norm_Re,K);
Con_tx_norm_Im = Con_tx_Im;%/sqrt(Ps);
Con_tx_para_Im = vec2mat(Con_tx_norm_Im,K);

% Index symbol
Bit_index_tx1 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para1 = vec2mat(Bit_index_tx1,bi);

Bit_index_tx2 = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para2 = vec2mat(Bit_index_tx2,bi);

% Subblock creation
Subblock_tx1 = Mapper_LLR_QIM(Bit_index_tx_para1,Con_tx_para_Re,N,K,G,Nsym);

Subblock_tx2 = Mapper_LLR_QIM(Bit_index_tx_para2,Con_tx_para_Im,N,K,G,Nsym);
% OFDM block creation

Subblock_tx=Subblock_tx1+1j*Subblock_tx2;
% scatterplot(Subblock_tx(:,1));

Tx = (reshape(Subblock_tx.',Ndata,Nsym)).';

% DFT spreading (localized)
DFT_input = Tx;
DFT_output = fft(DFT_input,Ndata,2);

% IFFT with HS
Tx_DFT = DFT_output;
Tx_DFT_conj = fliplr(conj(Tx_DFT));

IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Tx_DFT; % x1 and xN/2+1 are set to 0
IFFT_input(:,NF-Ndata+1:NF) = Tx_DFT_conj;
IFFT_output4QAM_42DFT = ifft(IFFT_input,NF,2); % oversample by lines


% PAPR
for i = 1:Nsym
    P4QAM_42DFT(i) = max(IFFT_output4QAM_42DFT(i,:).^2);
    P_av4QAM_42DFT(i) = mean(IFFT_output4QAM_42DFT(i,:).^2);
    PAPR4QAM_42DFT(i) = P4QAM_42DFT(i)/P_av4QAM_42DFT(i);
    PAPR_dB4QAM_42DFT(i) = 10*log10(PAPR4QAM_42DFT(i));
end

[f4QAM_42DFT,x4QAM_42DFT] = ecdf(PAPR_dB4QAM_42DFT);
ff4QAM_42DFT = 1 - f4QAM_42DFT;



%% SMIM_LLR_8QAM_42
% Parameter
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata =108; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K = 2; % K out of N subcarriers in each subblock are active

M = 8; % M-ary signal constellation (e.g., M-QAM)

% OFDM-SIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc = K*log2(M); % number of bits carried by constellations on active subcarriers 
b = bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');

Con_tx_norm = Con_tx;%/sqrt(Ps);
Con_tx_para = vec2mat(Con_tx_norm,K);
% scatterplot(reshape(Con_tx,1,size(Con_tx,1)*size(Con_tx,2)));

% Index symbol
Bit_index_tx = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para = vec2mat(Bit_index_tx,bi);

% Subblock creation
Subblock_tx = Mapper_LLR(Bit_index_tx_para,Con_tx_para,N,K,G,Nsym);
    % scatterplot(Subblock_tx(:,2));
% OFDM block creation
Data_tx = (reshape(Subblock_tx.',Ndata,Nsym)).';
 % scatterplot(Data_tx(:,24));

Data_tx_conj = fliplr(conj(Data_tx));

% IFFT with HS
IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Data_tx;
IFFT_input(:,NF-Ndata+1:NF) = Data_tx_conj;
IFFT_output8QAM_42 = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
%
for i = 1:Nsym
    P8QAM_42(i) = max(IFFT_output8QAM_42(i,:).^2);
    P_av8QAM_42(i) = mean(IFFT_output8QAM_42(i,:).^2);
    PAPR8QAM_42(i) = P8QAM_42(i)/P_av8QAM_42(i);
    PAPR_dB8QAM_42(i) = 10*log10(PAPR8QAM_42(i));
end

[f8QAM_42,x8QAM_42] = ecdf(PAPR_dB8QAM_42);
ff8QAM_42 = 1 - f8QAM_42;

%% SMIM_LLR_8QAM_42DFT
NF = 256; % OFDM block size, i.e., size of IFFT/FFT or total number of subcarriers
Ndata =108; % number of subcarriers used for data transmission
Nsym = 50000; % number of OFDM blocks

N = 4; % number of subcarriers in each subblock
K = 2; % K out of N subcarriers in each subblock are active

M = 8; % M-ary signal constellation (e.g., M-QAM)

%% OFDM-SIM transmitter
G = Ndata/N; % number of subblocks
Nc = nchoosek(N,K); % number of combinations
bi = floor(log2(Nc)); % number of bits carried by index selection
bc = K*log2(M); % number of bits carried by constellations on active subcarriers 
b = bi + bc; % number of bits transmitted per subblock
m = b*G; % number of bits transmitted per OFDM block

% Constellation symbol
Con_decimal = 0:(M-1);
S = qammod(Con_decimal,M,0,'gray');
Ps = mean(abs(S.^2));

Bit_con_tx = floor(rand(1,bc*G*Nsym)*2);
Bit_con_tx_para = vec2mat(Bit_con_tx,log2(M));
Decimal_con_tx = bi2de(Bit_con_tx_para,'left-msb');
Con_tx = qammod(Decimal_con_tx,M,0,'gray');

Con_tx_norm = Con_tx;%/sqrt(Ps);
Con_tx_para = vec2mat(Con_tx_norm,K);
% scatterplot(reshape(Con_tx,1,size(Con_tx,1)*size(Con_tx,2)));

% Index symbol
Bit_index_tx = floor(rand(1,bi*G*Nsym)*2);
Bit_index_tx_para = vec2mat(Bit_index_tx,bi);

% Subblock creation
Subblock_tx = Mapper_LLR(Bit_index_tx_para,Con_tx_para,N,K,G,Nsym);
    % scatterplot(Subblock_tx(:,2));
% OFDM block creation
Tx = (reshape(Subblock_tx.',Ndata,Nsym)).';

% DFT spreading (localized)
DFT_input = Tx;
DFT_output = fft(DFT_input,Ndata,2);

% IFFT with HS
Tx_DFT = DFT_output;
Tx_DFT_conj = fliplr(conj(Tx_DFT));

IFFT_input = zeros(Nsym,NF);
IFFT_input(:,2:Ndata+1) = Tx_DFT; % x1 and xN/2+1 are set to 0
IFFT_input(:,NF-Ndata+1:NF) = Tx_DFT_conj;
IFFT_output8QAM_42DFT = ifft(IFFT_input,NF,2); % oversample by lines

% PAPR
%
for i = 1:Nsym
    P8QAM_42DFT(i) = max(IFFT_output8QAM_42DFT(i,:).^2);
    P_av8QAM_42DFT(i) = mean(IFFT_output8QAM_42DFT(i,:).^2);
    PAPR8QAM_42DFT(i) = P8QAM_42DFT(i)/P_av8QAM_42DFT(i);
    PAPR_dB8QAM_42DFT(i) = 10*log10(PAPR8QAM_42DFT(i));
end

[f8QAM_42DFT,x8QAM_42DFT] = ecdf(PAPR_dB8QAM_42DFT);
ff8QAM_42DFT = 1 - f8QAM_42DFT;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure(1)
h1 = semilogy(x4QAM_41,ff4QAM_41,'--r',x4QAM_41DFT,ff4QAM_41DFT,'-r',x16QAM_41,ff16QAM_41,'--b',x16QAM_41DFT,ff16QAM_41DFT,'-b'); % CCDF of PAPR
axis([7 15 0.0038 1])
xlabel('PAPR (dB)','FontName','Times New Roman','FontSize',16,'FontWeight','bold');
ylabel('CCDF','FontName','Times New Roman','FontSize',16,'FontWeight','bold');
legend('OFDM with QIM,(4,1)','DFT-S-OFDM with QIM,(4,1)','OFDM with IM,(4,1)','DFT-S-OFDM with IM,(4,1)','location','best');
set(gca,'FontName','Times New Roman','FontSize',16,'FontWeight','bold');
set(gca,'linewidth',1.5); 
set(gcf,'Color',[1,1,1]);
set(h1,'MarkerSize',6,'linewidth',1.5)
set(gca,'TickLength',[0.015;0.025]);

figure(2)
h1 = semilogy(x_OFDM,ff_OFDM,'--m',x_OFDM_DFT,ff_OFDM_DFT,'-m',x4QAM_42,ff4QAM_42,'--r',x4QAM_42DFT,ff4QAM_42DFT,'-r',x8QAM_42,ff8QAM_42,'--b',x8QAM_42DFT,ff8QAM_42DFT,'-b'); % CCDF of PAPR
axis([7 15 0.0038 1])
xlabel('PAPR (dB)','FontName','Times New Roman','FontSize',16,'FontWeight','bold');
ylabel('CCDF','FontName','Times New Roman','FontSize',16,'FontWeight','bold');
legend('OFDM','DFT-S-OFDM','OFDM with QIM,(4,2)','DFT-S-OFDM with QIM,(4,2)','OFDM with IM,(4,2)','DFT-S-OFDM with IM,(4,2)','location','best');
set(gca,'FontName','Times New Roman','FontSize',16,'FontWeight','bold');
set(gca,'linewidth',1.5); 
set(gcf,'Color',[1,1,1]);
set(h1,'MarkerSize',6,'linewidth',1.5)
set(gca,'TickLength',[0.015;0.025]);