IEEE.org     |     IEEE Xplore Digital Library     |     IEEE Standards     |     IEEE Spectrum     |     More Sites

Commit c8b3b871 authored by Martin Hudlicka's avatar Martin Hudlicka
Browse files

New MATLAB codes

parent 54c974e1
function [NPR_EVM,NMSE] = F_NPR_NMSE_Oversampled_Signal(params, fxF, fxFideal)
global structGlobal
%------------------------------------------------------------
% computation of NPR and NMSE on oversampled signals spectra
%------------------------------------------------------------
%-------------------------------------------------------
% low pass filter on oversampled signal spectrum
%-------------------------------------------------------
if structGlobal.printdebug >1
fprintf('Low-pass filter on oversampled received signal\n');
end
filter = zeros(1, params.lxF);
% filter guard band in carrier bandwidth on each side
% optimum may vary with type and importance of impairments and value of Nc
% it can be 0 (less noise but more distortion)
filter_side = 5;
% filter bandwidth in number of df steps
bandwidth = min(params.lxF, floor((params.Nc + 2*filter_side)* params.DF/params.df));
if structGlobal.printdebug > 1
fprintf(' Filter relative bandwidth = %9.2f %%\n', 100*(params.Nc+2*filter_side)/params.Nc);
end
% filter stopband in number of df steps
stopband = floor((params.lxF -bandwidth)/2);
filter(stopband+1:params.lxF-stopband+1)= ones(1, params.lxF-2*stopband+1);
fxF = fxF .* filter;
Pavg=sum(abs(fxF).^2) / (params.lxF-2*stopband+1);
if structGlobal.printdebug >1
fprintf(' Average power in bandwidth after filter = %6.2f dB\n', 10*log10(Pavg));
end
% filtered signal
xF = F_fft_inverse(params, fxF);
%
if structGlobal.tracedebug >1
figure(14)
clf
grid on
title('Power spectrum of filtered received signal frame in dB');
hold on
freq = params.df*linspace(-floor(params.lxF/2), params.lxF -1 -floor(params.lxF/2), params.lxF);
plot(freq, max(-200,20*log10(abs(fxF))), 'r');
% smoothing on NS frequency samples
fx2int=zeros(1,params.lxprefguard);
for i=1:params.lxprefguard
fx2int(i)=sum(abs(fxF(params.NS*(i-1)+1:params.NS*i)).^2)/params.NS;
end
freq = params.df*(-floor(params.lxF/2)+floor(params.NS/2): params.NS : params.lxF-floor(params.lxF/2)+floor(params.NS/2)-1);
plot(freq, max(-200,10*log10(abs(fx2int))), 'k');
end
% New in version 3 and 4
% filter on ideal spectrum
fxFideal = fxFideal .* filter;
Pavg=sum(abs(fxFideal).^2) / (params.lxF-2*stopband+1);
if structGlobal.printdebug
fprintf(' Average power of ideal signal after low-pass filter = %6.2f dB\n', 10*log10(Pavg));
end
% filtered ideal signal
xFideal = F_fft_inverse(params, fxFideal);
%
if structGlobal.tracedebug >1
figure(15)
clf
grid on
title('Power spectrum of filtered ideal signal frame in dB');
hold on
freq = params.df*linspace(-floor(params.lxF/2),params.lxF -1-floor(params.lxF/2),params.lxF);
plot(freq, max(-200,20*log10(abs(fxFideal))), 'r');
% smoothing on NS frequency samples
fx2int=zeros(1,params.lxprefguard);
for i=1:params.lxprefguard
fx2int(i)=sum(abs(fxFideal(params.NS*(i-1)+1:params.NS*i)).^2)/params.NS;
end
freq = params.df*(-floor(params.lxF/2)+floor(params.NS/2): params.NS : params.lxF-floor(params.lxF/2)+floor(params.NS/2)-1);
plot(freq, max(-200,10*log10(abs(fx2int))), 'k');
end
%---------------------------------------------------------------------
% Auto and cross-correlations at time 0 for normalization of signals
%---------------------------------------------------------------------
CC = xF * xFideal';
ACideal = xFideal * xFideal';
AC = xF * xF';
% computation of optimum complex gain and error on oversampled signal
% these values are not correct if noise and IMD are not filtered
G0 = CC / ACideal;
fprintf('Optimum gain on oversampled signal with low-pass filter\n');
fprintf(' amplitude = %8.6f phase = %8.2f �\n',abs(G0), angle(G0)*180/pi );
%---------------------------------------------------------------
% computation of NPR or RF spectrum EVM on oversampled waveform
%---------------------------------------------------------------
cos2 = real(CC*conj(CC) / AC / ACideal);
if structGlobal.printdebug > 1
fprintf('Angle between measured signal and reference signal\n');
fprintf(' cos2 = %8.6f angle = %10.6f �\n',cos2,acos(sqrt(cos2))*180/pi );
end
NPR_EVM = sqrt(1/cos2-1); % = tangent of angle
fprintf('RF spectrum EVM (= in-band average NPR) with low-pass filter\n');
fprintf(' RF spectrum EVM or NPR = %8.4f %% or %6.2f dB\n',NPR_EVM * 100, -20*log10(NPR_EVM));
chord = 2 * sin(0.5 * acos(sqrt(cos2))); % twice sine of half angle
NMSE = chord^2;
fprintf(' RF spectrum NMSE = %6.2f dB\n', 10*log10(NMSE));
end
\ No newline at end of file
function [NPR_EVM, NMSE] = F_P1765_OFDM_NMSE_Algorithm(params,xFideal,xF)
% Computation of NPR and NMSE on oversampled signal
% Refer to Section 7.5 of the IEEE P1765 document.
% To use this function replace lines 166--169 in the main program:
% IEEE_P1765_Baseline_EVM_Algorithm_OFDM_Receive
% with the following function call :
% [NPR_EVM, NMSE] = F_P1765_OFDM_NMSE_Algorithm(params,xFideal,xF);
% The user can alternatively add the function call at the end of the main program.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Authors: Patrick Roblin and Jacques Sombrin
% Modularization performed by Paritosh Manurkar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% computation of spectrum of ideal signal
fxFideal = F_fft_direct(params, xFideal);
%% computation of spectrum of received signal
fxF = F_fft_direct(params, xF);
%% Time alignment (Step1:Coarse, Step2:Fine)
[delay,fxF] = F_calculateOptimal(params,fxFideal,fxF);
%% Computation of NPR and NMSE on oversampled signal / spectra
[NPR_EVM, NMSE] = F_NPR_NMSE_Oversampled_Signal(params,fxF,fxFideal);
%% Save NPR EVM as percent and NMSE in dB in a text file
F_Save_Results_NPR_EVM_NMSE(NPR_EVM*100, delay, 10*log10(NMSE));
fprintf('=================================================================\n')
end
\ No newline at end of file
function F_Save_Results_NPR_EVM_NMSE(NPR_EVM_pct, tau0, NMSEdB)
% This function saves the F_P1765_OFDM_NMSE_Algorithm's outputs
% NPR_EVM_pct: Baseline rms EVM in percent
% NMSEdB: Normalized mean square error in dB
global structGlobal
fname = strcat(structGlobal.filename_results,'_NMSE.txt');
fid = fopen(fullfile(structGlobal.evm_results_folder,fname),'w');
fprintf(fid,'\n\n');
fprintf(fid,'%s\n','RESULTS');
Quantity = [{'NPR EVM %', 'tau0-Optimal Delay (ns)', 'NMSE'}];
Value = [NPR_EVM_pct; tau0; NMSEdB];
fprintf(fid,'%s\n','------------------------------------------------');
fprintf(fid, '%s \t %s\r\n', 'Quantity', 'Value');
fprintf(fid,'%s\n','------------------------------------------------');
for n =1:length(Value)
fprintf(fid, '%-23s %1.15g\r\n', Quantity{n}, Value(n));
end
fprintf(fid,'\n\n');
fprintf(fid,'%s\n','Definition:');
fprintf(fid,'%s\n','-----------------------------');
fprintf(fid,'%s\n','> NPR EVM % = RF spectrum EVM (= in-band average NPR) with low-pass filter, in percent');
fprintf(fid,'%s\n','> NMSE = RF spectrum normalized mean square error as defined in Section 7.5, in dB');
fprintf(fid,'%s\n','> Optimal Delay (ns) = Optimal time delay in ns');
fclose(fid);
end
function [G_OPT,EVM] = F_EVM_Computation_on_Channels(params, Symb, Sideal)
% In this subroutine, the EVM and optimum gain Gsymb are computed separatly
% on the symbols of each frequency channels then they are averaged.
% For more details, refer to Section 9.1.2.
%
% This is equivalent to an equalization of the gains on channels
%
% Inputs:
% Symb or r(nT): Recovered OFDM symbols
% Sideal: Ideal OFDM symbols from ideal signal
% params: structure containing the basic communication paramters
%
% Outputs:
% G_OPT: Optimum gain on symbols for EVM computation
% EVM or Baseline signal EVM: Baseline rms EVM in percent
global structGlobal
%% %-----------------------------------------------------------
% Reshaping of ideal and received symbols and
% transposition giving Nc lines of NS symbols
%-----------------------------------------------------------
Symb = reshape(Symb, params.NS, params.Nc).';
Sideal = reshape(Sideal, params.NS, params.Nc).';
%% %-------------------------------------------------------------------------
% computation of optimum gain and EVM on symbols of each frequency carrier
%-------------------------------------------------------------------------
G_OPT = 0;
EVM2 = 0;
Gnc = zeros(1,params.Nc);
EVM2nc = zeros(1,params.Nc);
% loop on all channels (lines) and summation on columns
for nc = 1:params.Nc
% Auto and cross-correlations at time 0 for normalization of symbols
CC = dot(Symb(nc, :), Sideal(nc, :)); % conjugate of Symb(nc, :) * Sideal(nc, :)';
ACideal = dot(Sideal(nc, :) , Sideal(nc, :));
AC = dot(Symb(nc, :) , Symb(nc, :));
% normalization of symbols
Gnc(nc) = CC / AC;
% computation of EVM on symbols
cos2 = real(CC*conj(CC) / AC / ACideal);
EVM2nc(nc) = 1/cos2-1; % = square of tangent of angle
EVMnc = sqrt(EVM2nc(nc));
if (structGlobal.printdebug >2 && nc < 5 ) || structGlobal.printdebug > 3
fprintf('Optimum gain on symbols of channel %d for EVM computation\n', nc);
fprintf(' amplitude = %8.6f phase = %8.2f �\n',...
abs(Gnc(nc)), angle(Gnc(nc))*180/pi );
fprintf('Angle between measured symbols of channel %d and reference symbols\n', nc);
fprintf(' cos2 = %8.6f angle = %10.6f �\n',cos2,acosd(sqrt(cos2)));
fprintf('EVM measured on symbols of channel %d\n', nc);
fprintf(' EVM = %8.4f %% or %6.2f dB\n',EVMnc * 100, 20*log10(EVMnc));
end
EVM2 = EVM2 + EVM2nc(nc);
G_OPT = G_OPT + Gnc(nc);
end % of loop Nc
EVM = sqrt(EVM2 / params.Nc);
G_OPT = G_OPT / params.Nc;
if structGlobal.printdebug > 2
fprintf('\n');
end
fprintf('Average of optimum gain measured on symbols of each frequency channel\n');
fprintf(' amplitude = %8.6f phase = %8.2f �\n',...
abs(G_OPT), angle(G_OPT)*180/pi );
fprintf('Average of EVM measured separatly on symbols of each frequency channel\n');
fprintf(' EVM with equalization = %8.4f %% or %6.2f dB\n',EVM * 100, 20*log10(EVM));
%% Plot constellation for all symbols with average gain compensation
Symb = Symb * G_OPT * params.Ac;
Sideal = Sideal * params.Ac;
ColorV = 'rbgkcym';
if structGlobal.tracedebug >0
figure1 = figure(26); clf; grid on; box on;
hold on; axis('square');
axis([-params.N/2 params.N/2 -params.N/2 params.N/2]);
set(gca,'XTick',(-params.N/2:1:params.N/2));
set(gca,'YTick',(-params.N/2:1:params.N/2));
title({'Ideal and measured symbols constellations','(one color per frequency channel)'});
xlabel('Real part');
ylabel('Imaginary part');
plot(real(Sideal(1:params.Nc*params.NS)),imag(Sideal(1:params.Nc*params.NS)),'k*');
plot(params.Ac*cos(pi*(0:360)/180),params.Ac*sin(pi*(0:360)/180),'-b');
for nc = 1:params.Nc
color=ColorV(1+mod(nc,length(ColorV)));
plot(real(Symb(nc, :)),imag(Symb(nc, :)),[color,'o'])
end
legend({'Ideal symbols', 'Average level', 'Measured symbols'}, 'Location', 'eastoutside', 'Orientation', 'vertical');
% Saving figure as graphic file in current directory (plot must still be present in MATLAB plot window)
stri_fig = fullfile(structGlobal.evm_results_folder,strcat(structGlobal.filename_constellation,'_with_average_gain.jpg')); % Change file naming to save as needed
set(figure1,'PaperPositionMode','auto');
print(figure1,stri_fig,'-djpeg','-r0');
end
%% Plot constellation for all symbols without echo
if structGlobal.tracedebug >0
figure1 = figure(27); clf; grid on; box on;
hold on; axis('square');
axis([-params.N/2 params.N/2 -params.N/2 params.N/2]);
set(gca,'XTick',(-params.N/2:1:params.N/2));
set(gca,'YTick',(-params.N/2:1:params.N/2));
title({'Ideal and measured symbols contellations','after echo equalization'});
xlabel('Real part');
ylabel('Imaginary part');
plot(real(Sideal(1:params.Nc*params.NS)),imag(Sideal(1:params.Nc*params.NS)),'k*');
plot(params.Ac*cos(pi*(0:360)/180),params.Ac*sin(pi*(0:360)/180),'-b');
for nc = 1:params.Nc
Symb(nc, :) = Symb(nc, :) * G_OPT / Gnc(nc);
color=ColorV(1+mod(nc,length(ColorV)));
plot(real(Symb(nc, :)),imag(Symb(nc, :)),[color,'o'])
end
legend({'Ideal symbols', 'Average level', 'Measured symbols'}, 'Location', 'eastoutside', 'Orientation', 'vertical');
% Saving figure as graphic file in current directory (plot must still be present in MATLAB plot window)
stri_fig = fullfile(structGlobal.evm_results_folder,strcat(structGlobal.filename_constellation,'_with_equalization.jpg')); % Change file naming to save as needed
set(figure1,'PaperPositionMode','auto');
print(figure1,stri_fig,'-djpeg','-r0');
end
%% Plot optimum gain and EVM versus frequency channel
if structGlobal.tracedebug >1
figure(28); clf; grid on; hold on;
title('Relative gain and phase on measured symbols on each frequency channel');
xlabel('Frequency channel number');
ylabel('Relative gain amplitude (dB) or relative gain phase (�)');
Gdb = 20*log10(abs(Gnc/G_OPT));
Gfi = angle(Gnc/G_OPT) * 180 / pi;
plot(1:params.Nc, Gdb,'k-');
plot(1:params.Nc, Gfi,'r-');
legend({'Relative gain amplitude', 'Relative gain phase'}, 'Location', 'southeast');
figure(29); clf; grid on; hold on;
title('EVM on each frequency channel and average EVM');
xlabel('Frequency channel number');
ylabel('EVM (%)');
plot(1:params.Nc, sqrt(EVM2nc)*100,'k-');
plot([1 params.Nc], [EVM*100 EVM*100 ],'r-');
legend({'EVM on each channel', 'Average EVM'}, 'Location', 'southeast');
end
end
function [GSymb,EVM_with_equalization] = F_P1765_OFDM_Baseline_EVM_Algorithm_with_equalization(params,xFideal,xF)
% Calculate average of EVM on frequency channels e.g. with equalization
% This function implements the OFDM Baseline EVM Algorithm with Equalization.
% Refer to Section 9.1.2 of the IEEE P1765 document.
% To use this function replace lines 166--169 in the main program:
% IEEE_P1765_Baseline_EVM_Algorithm_OFDM_Receive
% with the following function call :
% [G_OPT2,EVM_with_equalization] = F_P1765_OFDM_Baseline_EVM_Algorithm_with_equalization(params, xFideal, xF);
% The user can alternatively add the function call at the end of the main program.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Authors: Patrick Roblin and Jacques Sombrin
% Modularization performed by Paritosh Manurkar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% computation of spectrum of ideal signal
fxFideal = F_fft_direct(params, xFideal);
%% computation of spectrum of received signal
fxF = F_fft_direct(params, xF);
%% Time alignment (Step1:Coarse, Step2:Fine)
[delay,fxF] = F_calculateOptimal(params,fxFideal,fxF);
%% Time aligned measured signal computed from its spectrum
xF = F_fft_inverse(params, fxF);
%% OFDM Symbols Recovery (Step3)
Symb = F_OFDM_Symbols_Recovery(params,xF);
%% Ideal OFDM symbols Recovery, identical to step 3 but from ideal signal
Sideal = F_OFDM_Symbols_Recovery(params,xFideal);
%% Average of EVM computed on channels, EVM_with_equalization
[GSymb,EVM_with_equalization] = F_EVM_Computation_on_Channels(params, Symb, Sideal);
%% Save EVM with equalization as percent and G_OPT value in a text file
F_Save_Results_EVM_with_equalization(EVM_with_equalization*100, delay, GSymb)
fprintf('=================================================================\n')
end
\ No newline at end of file
function F_Save_Results_EVM_with_equalization(EVM_with_eq_pct, tau0, G_OPT_avg_ch)
% This function saves the outputs from the EVM_Computation_on_Channels
% EVM_with_eq_pct: EVM with equalization in percent
% tau0: Optimal time delay
% G_OPT_avg_ch: Optimal complex gain / normalization factor for symbol samples
% (saved as absolute and phase parts)
global structGlobal
G_OPT_avg_ch_amp = abs(G_OPT_avg_ch);
G_OPT_avg_ch_phase = angle(G_OPT_avg_ch)*180/pi; % degrees
fname = strcat(structGlobal.filename_results,'_with_equalization.txt');
fid = fopen(fullfile(structGlobal.evm_results_folder,fname),'w');
fprintf(fid,'\n\n');
fprintf(fid,'%s\n','RESULTS');
Quantity = [{'EVM %', 'tau0-Optimal Delay (ns)', 'G_OPT Avg Ch Amp', 'G_OPT Avg Ch Phase (deg)'}];
Value = [EVM_with_eq_pct; tau0; G_OPT_avg_ch_amp; G_OPT_avg_ch_phase];
fprintf(fid,'%s\n','------------------------------------------------');
fprintf(fid, '%s \t %s\r\n', 'Quantity', 'Value');
fprintf(fid,'%s\n','------------------------------------------------');
for n =1:length(Value)
fprintf(fid, '%-23s %1.15g\r\n', Quantity{n}, Value(n));
end
fprintf(fid,'\n\n');
fprintf(fid,'%s\n','Definition:');
fprintf(fid,'%s\n','-----------------------------');
fprintf(fid,'%s\n','> EVM % = Average of EVM measured separatly on symbols of each frequency channel');
fprintf(fid,'%s\n','> that is, EVM with equalization, in percent');
fprintf(fid,'%s\n','> Optimal Delay (ns) = Optimal time delay in ns');
fprintf(fid,'%s\n','> G_OPT Avg Ch is the average of optimum gain measured on symbols of each frequency channel');
fprintf(fid,'%s\n','> G_OPT Avg Ch Amp = abs(G_OPT Avg Ch)');
fprintf(fid,'%s\n','> G_OPT Avg Ch Phase = angle(G_OPT Avg Ch) in degrees');
fclose(fid);
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment