%===================================
% This is the simulator for SC-FDMA.
%===================================
function [SER ifdma SER lfdma] = scfdma(SP)
numSymbols = SP.FFTsize; % The number of transmitted SC-FDMA symbols.
Q = numSymbols/SP.inputBlockSize; % The bandwidth spreading factor.
% Frequency domain version of the channel response.
H_channel = fft(SP.channel,SP.FFTsize);
for n = 1:length(SP.SNR),
% Initialize the error count.
errCount_ifdma = 0;
errCount_lfdma = 0;
for k = 1:SP.numRun,
% Generate random data block.
tmp = round(rand(2,SP.inputBlockSize));
tmp = tmp*2 - 1;
inputSymbols = (tmp(1,:) + i*tmp(2,:))/sqrt(2);
% DFT-precoding.
inputSymbols_freq = fft(inputSymbols);
% Initialize the output subcarriers.
inputSamples_ifdma = zeros(1,numSymbols);
inputSamples_lfdma = zeros(1,numSymbols);
% Subcarrier mapping.
% Interleaved (distributed) mapping.
inputSamples_ifdma(1+SP.subband:Q:numSymbols) = inputSymbols_freq;
% Localized mapping.
inputSamples_lfdma([1:SP.inputBlockSize]+SP.inputBlockSize*SP.subband) = inputSymbols_freq;
% Convert the signal back to time domain.
inputSamples_ifdma = ifft(inputSamples_ifdma);
inputSamples_lfdma = ifft(inputSamples_lfdma);
% Add CP.
TxSamples_ifdma = [inputSamples_ifdma(numSymbols - SP.CPsize+1:numSymbols) inputSamples_ifdma];
TxSamples_lfdma = [inputSamples_lfdma(numSymbols - SP.CPsize+1:numSymbols) inputSamples_lfdma];
% Propagate through multi-path channel.
RxSamples_ifdma = filter(SP.channel, 1, TxSamples_ifdma);
RxSamples_lfdma = filter(SP.channel, 1, TxSamples_lfdma);
% Generate AWGN with appropriate noise power.
tmp = randn(2, numSymbols+SP.CPsize);
complexNoise = (tmp(1,:) + i*tmp(2,:))/sqrt(2);
noisePower = 10^(-SP.SNR(n)/10);
% Add AWGN to the transmitted signal.
RxSamples_ifdma = RxSamples_ifdma + sqrt(noisePower/Q)*complexNoise;
RxSamples_lfdma = RxSamples_lfdma + sqrt(noisePower/Q)*complexNoise;
% Remove CP.
RxSamples_ifdma = RxSamples_ifdma(SP.CPsize+1:numSymbols+SP.CPsize);
RxSamples_lfdma = RxSamples_lfdma(SP.CPsize+1:numSymbols+SP.CPsize);
% Convert the received signal into frequency domain.
Y_ifdma = fft(RxSamples_ifdma, SP.FFTsize);
Y_lfdma = fft(RxSamples_lfdma, SP.FFTsize);
% Subcarrier de-mapping.
Y_ifdma = Y_ifdma(1+SP.subband:Q:numSymbols);
Y_lfdma = Y_lfdma([1:SP.inputBlockSize]+SP.inputBlockSize*SP.subband);
% Find the channel response for the interleaved subcarriers.
H_eff = H_ channel(1+SP.subband:Q:numSymbols);
% Perform channel equalization in the frequency domain.
if SP.equalizerType == 'ZERO'
Y_ifdma = Y_ifdma./H_eff;
elseif SP.equalizerType == 'MMSE'
C = conj(H_eff)./(conj(H_eff).*H_eff + 10^(-SP.SNR(n)/10));
Y_ifdma = Y_ifdma.*C;
end
% Find the channel response for the localized subcarriers.
H_eff = H_channel([1:SP.inputBlockSize]+SP.inputBlockSize*SP.subband);
% Perform channel equalization in the frequency domain.
if SP.equalizerType == 'ZERO'
Y_lfdma = Y_lfdma./H_eff;
elseif SP.equalizerType == 'MMSE'
C = conj(H_eff)./(conj(H_eff).*H_eff + 10^(-SP.SNR(n)/10));
Y_lfdma = Y_lfdma.*C;
end
% Convert the signal back to time domain.
EstSymbols_ifdma = ifft(Y_ifdma);
EstSymbols_lfdma = ifft(Y_lfdma);
% Perform hard decision detection.
EstSymbols_ifdma = sign(real(EstSymbols_ifdma)) + i*sign(imag(EstSymbols_ifdma));
EstSymbols_ifdma = EstSymbols_ifdma/sqrt(2);
EstSymbols_lfdma = sign(real(EstSymbols_lfdma)) + i*sign(imag(EstSymbols_lfdma));
EstSymbols_lfdma = EstSymbols_lfdma/sqrt(2);
% Find and count errors.
I_ifdma = find((inputSymbols-EstSymbols_ifdma) == 0);
errCount_ifdma = errCount_ifdma + (SP.inputBlockSize-length(I_ifdma));
I_lfdma = find((inputSymbols-EstSymbols_lfdma) == 0);
errCount_lfdma = errCount_lfdma + (SP.inputBlockSize-length(I_lfdma));
end
% Calculate the symbol error rate (SER).
SER_ifdma(n,:) = errCount_ifdma /(SP.inputBlockSize*SP.numRun);
SER_lfdma(n,:) = errCount_lfdma /(SP.inputBlockSize*SP.numRun);
end