Scattered stuff from Silas during Dissertation
This commit is contained in:
@@ -4,6 +4,8 @@ arguments
|
||||
ref_symbols
|
||||
options.fignum (1,1) double = NaN % Default to NaN if not provided
|
||||
options.displayname (1,:) char = '' % Default to an empty string if not provided
|
||||
options.ref_symbol_uncoded = []
|
||||
options.nbins (1,1) double = 1000
|
||||
end
|
||||
|
||||
if isa(eq_signal,'Signal')
|
||||
@@ -12,6 +14,20 @@ end
|
||||
if isa(ref_symbols,'Signal')
|
||||
ref_symbols = ref_symbols.signal;
|
||||
end
|
||||
if isa(options.ref_symbol_uncoded,'Signal')
|
||||
options.ref_symbol_uncoded = options.ref_symbol_uncoded.signal;
|
||||
end
|
||||
|
||||
eq_signal = eq_signal(:);
|
||||
ref_symbols = ref_symbols(:);
|
||||
ref_symbol_uncoded = options.ref_symbol_uncoded(:);
|
||||
|
||||
assert(numel(eq_signal) == numel(ref_symbols), ...
|
||||
'showLevelHistogram:LengthMismatch', ...
|
||||
'eq_signal and ref_symbols must have the same number of samples.');
|
||||
assert(isempty(ref_symbol_uncoded) || numel(ref_symbol_uncoded) == numel(eq_signal), ...
|
||||
'showLevelHistogram:LengthMismatch', ...
|
||||
'options.ref_symbol_uncoded must have the same number of samples as eq_signal.');
|
||||
|
||||
% Determine the figure number to use or create a new figure
|
||||
if isnan(options.fignum)
|
||||
@@ -22,31 +38,70 @@ end
|
||||
|
||||
eq_signal = max(min(eq_signal,3),-3);
|
||||
|
||||
%%% Separate Classes
|
||||
constellation = unique(ref_symbols);
|
||||
received_sd = NaN(numel(constellation),length(ref_symbols));
|
||||
lvlcol = cbrewer2('Paired',numel(constellation)*2);
|
||||
lvlcol = lvlcol(2:2:end,:);
|
||||
lvlcol = linspecer(numel(constellation));
|
||||
% lvlcol = cbrewer2('Set1',numel(constellation));
|
||||
for lvl = 1:numel(constellation)
|
||||
%Separate the equalized signal into the
|
||||
%respective levels based on the actually
|
||||
%transmitted level!
|
||||
received_sd(lvl,ref_symbols==constellation(lvl)) = eq_signal(ref_symbols==constellation(lvl));
|
||||
end
|
||||
|
||||
% scaling = PAMmapper(numel(constellation),0).get_scaling;
|
||||
|
||||
%%% FFE histogram
|
||||
%%% histogram
|
||||
clf
|
||||
for lvl = 1:numel(constellation)
|
||||
intermediate = received_sd(lvl,:);
|
||||
cnt(lvl) = round(numel(intermediate(~isnan(intermediate)))./length(eq_signal),3).*100;
|
||||
hold on
|
||||
warning off
|
||||
histogram(received_sd(lvl,:),1000,"EdgeAlpha",0,'DisplayName',['Lvl ',num2str(lvl),' ; ',num2str(cnt(lvl)),' '],'FaceColor',lvlcol(lvl,:),'Normalization','pdf');
|
||||
warning on
|
||||
if isempty(ref_symbol_uncoded)
|
||||
% Normal mode: split the received signal by the actually
|
||||
% transmitted reference level.
|
||||
constellation = unique(ref_symbols);
|
||||
received_sd = NaN(numel(constellation),numel(ref_symbols));
|
||||
lvlcol = linspecer(numel(constellation));
|
||||
|
||||
for lvl = 1:numel(constellation)
|
||||
class_mask = ref_symbols == constellation(lvl);
|
||||
received_sd(lvl,class_mask) = eq_signal(class_mask);
|
||||
end
|
||||
|
||||
for lvl = 1:numel(constellation)
|
||||
intermediate = received_sd(lvl,:);
|
||||
cnt(lvl) = round(numel(intermediate(~isnan(intermediate)))./numel(eq_signal),3).*100;
|
||||
hold on
|
||||
warning off
|
||||
histogram(received_sd(lvl,:),options.nbins, ...
|
||||
"EdgeAlpha",0, ...
|
||||
"DisplayName",['Lvl ',num2str(lvl),' ; ',num2str(cnt(lvl)),' '], ...
|
||||
"FaceColor",lvlcol(lvl,:), ...
|
||||
"Normalization","pdf");
|
||||
warning on
|
||||
end
|
||||
else
|
||||
% Plot p(y | x_n): y is the noisy observation and x_n is the
|
||||
% uncoded PAM class. For duobinary this naturally gives multi-modal
|
||||
% PDFs because one x_n class can map to multiple DB amplitudes. Each
|
||||
% DB lobe is drawn separately so the DB-level structure stays visible.
|
||||
db_constellation = unique(ref_symbols);
|
||||
classes = unique(ref_symbol_uncoded);
|
||||
lvlcol = linspecer(numel(classes));
|
||||
|
||||
for db_lvl = 1:numel(db_constellation)
|
||||
db_mask = ref_symbols == db_constellation(db_lvl);
|
||||
mapped_class = mode(ref_symbol_uncoded(db_mask));
|
||||
[~,class_idx] = min(abs(classes - mapped_class));
|
||||
cnt = round(nnz(ref_symbol_uncoded == mapped_class)./numel(eq_signal),3).*100;
|
||||
|
||||
if db_lvl == findFirstMappedDbLevel(ref_symbols,ref_symbol_uncoded,db_constellation,mapped_class)
|
||||
display_name = ['p(y|x_',num2str(class_idx),') ; ',num2str(cnt),' '];
|
||||
display_name = ['p(y|x_',num2str(class_idx),')'];
|
||||
handle_visibility = "on";
|
||||
else
|
||||
display_name = ['p(y|x_',num2str(class_idx),') ; ',num2str(cnt),' '];
|
||||
display_name = ['p(y|x_',num2str(class_idx),')'];
|
||||
handle_visibility = "off";
|
||||
end
|
||||
|
||||
weighted_lobe = NaN(size(eq_signal));
|
||||
weighted_lobe(db_mask) = eq_signal(db_mask);
|
||||
|
||||
hold on
|
||||
warning off
|
||||
histogram(weighted_lobe,options.nbins, ...
|
||||
"EdgeAlpha",0, ...
|
||||
"DisplayName",display_name, ...
|
||||
"FaceColor",lvlcol(class_idx,:), ...
|
||||
"HandleVisibility",handle_visibility, ...
|
||||
"Normalization","pdf");
|
||||
warning on
|
||||
end
|
||||
end
|
||||
xlim([-3 3]);
|
||||
legend
|
||||
@@ -58,3 +113,15 @@ end
|
||||
|
||||
end
|
||||
|
||||
function first_db_lvl = findFirstMappedDbLevel(ref_symbols,ref_symbol_uncoded,db_constellation,mapped_class)
|
||||
first_db_lvl = NaN;
|
||||
|
||||
for db_lvl = 1:numel(db_constellation)
|
||||
db_mask = ref_symbols == db_constellation(db_lvl);
|
||||
if mode(ref_symbol_uncoded(db_mask)) == mapped_class
|
||||
first_db_lvl = db_lvl;
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user