Scattered stuff from Silas during Dissertation
This commit is contained in:
@@ -4,6 +4,12 @@ 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.color = [];
|
||||
options.clear = true;
|
||||
options.rasterize = false;
|
||||
options.raster_resolution (1,1) double = 1000;
|
||||
options.raster_markersize (1,1) double = 1;
|
||||
options.raster_clim = [];
|
||||
end
|
||||
|
||||
plot_shit = 1;
|
||||
@@ -22,7 +28,9 @@ if plot_shit
|
||||
fig = figure; % Create a new figure and get its handle
|
||||
else
|
||||
fig = figure(options.fignum); % Use the specified figure number
|
||||
clf;
|
||||
if options.clear
|
||||
clf;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,6 +39,8 @@ rx_symbols = eq_signal; %./ rms(eq_signal);
|
||||
correct_symbols = ref_symbols;
|
||||
|
||||
col = cbrewer2('Paired',numel(unique(correct_symbols))*3);
|
||||
useDefaultColormap = isempty(options.color);
|
||||
scatterColor = options.color;
|
||||
ccnt = -1;
|
||||
|
||||
levels = unique(correct_symbols);
|
||||
@@ -66,20 +76,146 @@ D = sqrt(D_even.^2 + D_odd.^2);
|
||||
|
||||
[X,Y] = meshgrid(levels, levels);
|
||||
[X_,Y_] = meshgrid(statistical_mean, statistical_mean);
|
||||
plot_xlim = [floor(min(X_(:)))-1, ceil(max(X_(:)))+1];
|
||||
plot_ylim = [floor(min(Y_(:)))-1, ceil(max(Y_(:)))+1];
|
||||
|
||||
hold on;
|
||||
scatter(rx_even,rx_odd,5*ones(1,length(D)),D,'.','DisplayName',['Even/Odd PAM-',num2str(M)],'MarkerEdgeColor',col(2,:));
|
||||
% colormap(gca,flip(cbrewer2('Spectral',100)))
|
||||
colormap(gca,'hsv');
|
||||
scatter(X_(:), Y_(:), 2, 'x', 'LineWidth', 10, 'MarkerEdgeColor', col(6,:),'DisplayName','Statistical Rx Levels');
|
||||
scatter(X(:), Y(:), 2, 'x', 'LineWidth', 10, 'MarkerEdgeColor', col(4,:),'DisplayName','Tx Levels');
|
||||
xlim([floor(min(X_(:)))-1, ceil(max(X_(:)))+1]);
|
||||
ylim([floor(min(Y_(:)))-1, ceil(max(Y_(:)))+1]);
|
||||
if isempty(options.displayname)
|
||||
displayName = ['Even/Odd PAM-',num2str(M)];
|
||||
else
|
||||
displayName = options.displayname;
|
||||
end
|
||||
if useDefaultColormap
|
||||
cols = flip(cbrewer2('RdYlBu',100));
|
||||
cols=(cbrewer2("RdYlBu",4096));
|
||||
% cols(45:55,:) = [];
|
||||
colormap(gca,cols);
|
||||
if isempty(options.raster_clim)
|
||||
cLim = [0 max(D).*0.45];
|
||||
else
|
||||
cLim = options.raster_clim;
|
||||
end
|
||||
if cLim(2) <= cLim(1)
|
||||
cLim(2) = cLim(1) + eps;
|
||||
end
|
||||
clim(cLim);
|
||||
% colormap(gca,'hsv');
|
||||
if options.rasterize
|
||||
nBins = options.raster_resolution;
|
||||
xEdges = linspace(plot_xlim(1),plot_xlim(2),nBins+1);
|
||||
yEdges = linspace(plot_ylim(1),plot_ylim(2),nBins+1);
|
||||
xBin = discretize(rx_even,xEdges);
|
||||
yBin = discretize(rx_odd,yEdges);
|
||||
valid = ~isnan(xBin) & ~isnan(yBin) & isfinite(D);
|
||||
|
||||
yticks((levels(1:end-1) + levels(2:end)) / 2);
|
||||
xticks((levels(1:end-1) + levels(2:end)) / 2);
|
||||
countImg = accumarray([yBin(valid), xBin(valid)],1,[nBins nBins],@sum,0);
|
||||
dImg = accumarray([yBin(valid), xBin(valid)],D(valid),[nBins nBins],@mean,NaN);
|
||||
countImgRaw = countImg;
|
||||
markerRadius = max(0, round((options.raster_markersize - 1) / 2));
|
||||
if markerRadius > 0
|
||||
kernel = ones(2*markerRadius+1);
|
||||
countImg = conv2(countImg,kernel,'same');
|
||||
weightedD = dImg;
|
||||
weightedD(~isfinite(weightedD)) = 0;
|
||||
weightedD = conv2(weightedD .* countImgRaw,kernel,'same');
|
||||
dWeight = conv2(isfinite(dImg) .* countImgRaw,kernel,'same');
|
||||
dImg = weightedD ./ dWeight;
|
||||
end
|
||||
colorIdx = round((dImg-cLim(1)) ./ diff(cLim) * (size(cols,1)-1)) + 1;
|
||||
colorIdx = min(max(colorIdx,1),size(cols,1));
|
||||
|
||||
density = log1p(countImg);
|
||||
if max(density(:)) > 0
|
||||
density = density ./ max(density(:));
|
||||
end
|
||||
|
||||
rgbImg = ones(nBins,nBins,3);
|
||||
for rgbIdx = 1:3
|
||||
colorPlane = reshape(cols(colorIdx,rgbIdx),nBins,nBins);
|
||||
colorPlane(~isfinite(dImg)) = 1;
|
||||
rgbImg(:,:,rgbIdx) = (1-density) + density .* colorPlane;
|
||||
end
|
||||
|
||||
hImg = image(linspace(plot_xlim(1),plot_xlim(2),nBins), ...
|
||||
linspace(plot_ylim(1),plot_ylim(2),nBins), ...
|
||||
rgbImg);
|
||||
hImg.HandleVisibility = 'off';
|
||||
set(gca,'YDir','normal');
|
||||
uistack(hImg,'bottom');
|
||||
plot(nan,nan,'.','DisplayName',displayName,'MarkerEdgeColor',col(2,:));
|
||||
else
|
||||
sz = ones(1,length(D)).*1;
|
||||
scatter(rx_even,rx_odd,sz,D,'.','DisplayName',displayName);
|
||||
end
|
||||
rxLevelColor = col(6,:);
|
||||
else
|
||||
if options.rasterize
|
||||
nBins = options.raster_resolution;
|
||||
xEdges = linspace(plot_xlim(1),plot_xlim(2),nBins+1);
|
||||
yEdges = linspace(plot_ylim(1),plot_ylim(2),nBins+1);
|
||||
xBin = discretize(rx_even,xEdges);
|
||||
yBin = discretize(rx_odd,yEdges);
|
||||
valid = ~isnan(xBin) & ~isnan(yBin);
|
||||
|
||||
countImg = accumarray([yBin(valid), xBin(valid)],1,[nBins nBins],@sum,0);
|
||||
markerRadius = max(0, round((options.raster_markersize - 1) / 2));
|
||||
if markerRadius > 0
|
||||
kernel = ones(2*markerRadius+1);
|
||||
countImg = conv2(countImg,kernel,'same');
|
||||
end
|
||||
density = log1p(countImg);
|
||||
if max(density(:)) > 0
|
||||
density = density ./ max(density(:));
|
||||
end
|
||||
|
||||
rgbImg = ones(nBins,nBins,3);
|
||||
for rgbIdx = 1:3
|
||||
rgbImg(:,:,rgbIdx) = (1-density) + density .* scatterColor(rgbIdx);
|
||||
end
|
||||
|
||||
hImg = image(linspace(plot_xlim(1),plot_xlim(2),nBins), ...
|
||||
linspace(plot_ylim(1),plot_ylim(2),nBins), ...
|
||||
rgbImg);
|
||||
hImg.HandleVisibility = 'off';
|
||||
set(gca,'YDir','normal');
|
||||
uistack(hImg,'bottom');
|
||||
plot(nan,nan,'.','DisplayName',displayName,'MarkerEdgeColor',scatterColor);
|
||||
else
|
||||
scatter(rx_even,rx_odd,5*ones(1,length(D)),'.','DisplayName',displayName,'MarkerEdgeColor',scatterColor);
|
||||
end
|
||||
rxLevelColor = scatterColor;
|
||||
end
|
||||
|
||||
scatter(X_(:), Y_(:), 2, 'x', 'LineWidth', 10, 'MarkerEdgeColor', rxLevelColor,'DisplayName',[displayName, ' Rx Levels']);
|
||||
scatter(X(:), Y(:), 2, 'x', 'LineWidth', 10, 'MarkerEdgeColor', col(4,:),'DisplayName','Tx Levels');
|
||||
xlim(plot_xlim);
|
||||
ylim(plot_ylim);
|
||||
|
||||
decisionBoundaries = (levels(1:end-1) + levels(2:end)) / 2;
|
||||
ax = gca;
|
||||
xticks(levels);
|
||||
yticks(levels);
|
||||
xticklabels(compose('%g',levels));
|
||||
yticklabels(compose('%g',levels));
|
||||
try
|
||||
ax.XAxis.MinorTickValues = decisionBoundaries;
|
||||
ax.YAxis.MinorTickValues = decisionBoundaries;
|
||||
end
|
||||
ax.XMinorTick = 'on';
|
||||
ax.YMinorTick = 'on';
|
||||
ax.XMinorGrid = 'on';
|
||||
ax.YMinorGrid = 'on';
|
||||
ax.GridLineStyle = '--';
|
||||
ax.MinorGridLineStyle = ':';
|
||||
ax.GridColor = [0.65 0.65 0.65];
|
||||
ax.MinorGridColor = [0.35 0.35 0.35];
|
||||
ax.GridAlpha = 0.35;
|
||||
ax.MinorGridAlpha = 0.45;
|
||||
legend
|
||||
xlabel('even symbols');
|
||||
ylabel('odd symbols');
|
||||
axis equal; grid on;
|
||||
axis equal;
|
||||
grid on;
|
||||
grid minor;
|
||||
ax.Layer = 'top';
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ arguments
|
||||
options.postfilter_taps = NaN
|
||||
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.color = [0.2157 0.4941 0.7216];
|
||||
options.color = [];
|
||||
end
|
||||
|
||||
% Determine the figure number to use or create a new figure
|
||||
@@ -16,12 +16,14 @@ end
|
||||
hold on
|
||||
ax = gca;
|
||||
% N = numel(ax.Children);
|
||||
N = sum(arrayfun(@(x) strcmp(x.LineStyle, '-'), ax.Children));
|
||||
cmap = linspecer(8);
|
||||
options.color = cmap(mod(N, size(cmap, 1)) + 1, :);
|
||||
if isempty(options.color)
|
||||
N = sum(arrayfun(@(x) strcmp(x.LineStyle, '-'), ax.Children));
|
||||
cmap = linspecer(8);
|
||||
options.color = cmap(mod(N, size(cmap, 1)) + 1, :);
|
||||
end
|
||||
|
||||
% Ensure the figure is ready before calling spectrum
|
||||
eq_noise.spectrum("displayname", options.displayname, "fignum", fig.Number, "normalizeTo0dB", 1,"color",options.color);
|
||||
eq_noise.spectrum("displayname", options.displayname, "fignum", fig.Number, "normalizeTo0dB", 0,"color",options.color);
|
||||
|
||||
if ~isnan(options.postfilter_taps)
|
||||
% Hold on to the figure for further plotting
|
||||
|
||||
@@ -6,7 +6,8 @@ arguments
|
||||
options.fs_rx
|
||||
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.color = [0.2157 0.4941 0.7216];
|
||||
options.color = [];
|
||||
options.linestyle = '-';
|
||||
end
|
||||
|
||||
% Determine the figure number to use or create a new figure
|
||||
@@ -30,42 +31,52 @@ end
|
||||
ax = gca;
|
||||
|
||||
% N = numel(ax.Children);
|
||||
N = sum(arrayfun(@(x) strcmp(x.LineStyle, '-'), ax.Children));
|
||||
cmap = linspecer(8);
|
||||
options.color = cmap(mod(N, size(cmap, 1)) + 1, :);
|
||||
|
||||
% Ensure the figure is ready before calling spectrum
|
||||
title('SNR of received Signal')
|
||||
if isempty(options.color)
|
||||
N = sum(arrayfun(@(x) strcmp(x.LineStyle, '-'), ax.Children));
|
||||
cmap = linspecer(8);
|
||||
options.color = cmap(mod(N, size(cmap, 1)) + 1, :);
|
||||
end
|
||||
|
||||
fft_length = 2^(nextpow2(length(eq_signal))-7);
|
||||
|
||||
[s_lin,w] = pwelch(eq_signal,hanning(fft_length),fft_length/2,fft_length,options.fs_tx,"centered","psd","mean");
|
||||
[n_lin,w] = pwelch(noise_signal,hanning(fft_length),fft_length/2,fft_length,options.fs_rx,"centered","psd","mean");
|
||||
[n_lin,w_noise] = pwelch(noise_signal,hanning(fft_length),fft_length/2,fft_length,options.fs_rx,"centered","psd","mean");
|
||||
|
||||
if numel(w_noise) ~= numel(w) || any(abs(w_noise - w) > max(options.fs_tx,options.fs_rx)*eps)
|
||||
n_lin = interp1(w_noise,n_lin,w,"linear",NaN);
|
||||
end
|
||||
|
||||
w = w.*1e-9;
|
||||
snr_dbm = 10*log10(s_lin./n_lin);
|
||||
snr_lin = s_lin./n_lin;
|
||||
snr_lin = movmean(snr_lin,10);
|
||||
snr_dbm = 10*log10(snr_lin);
|
||||
|
||||
% figure(231)
|
||||
hold on
|
||||
plot(w,snr_dbm,'DisplayName','SNR','LineWidth',0.5,'Color',options.color);
|
||||
yline(mean(snr_dbm),'HandleVisibility','off','Color',options.color);
|
||||
if isempty(options.displayname)
|
||||
options.displayname = 'SNR';
|
||||
end
|
||||
|
||||
plot(w,snr_dbm,'DisplayName',options.displayname,'LineWidth',1,'Color',options.color,'LineStyle',options.linestyle);
|
||||
% yline(mean(snr_dbm),'HandleVisibility','off','Color',options.color,'LineStyle','--','LineWidth',1);
|
||||
xlabel("Frequency in GHz");
|
||||
|
||||
edgetick = 2^(nextpow2(options.fs_tx*1e-9));
|
||||
ticks = -edgetick:16:edgetick;
|
||||
xticks(ticks);
|
||||
|
||||
[~,b]=min(abs((-edgetick:16:edgetick)-max(w)));
|
||||
xlim([-ticks(b+1) ticks(b+1)]);
|
||||
ylabel("SNR (dB)");
|
||||
xlim([min(w) max(w)]);
|
||||
|
||||
max_snr = ceil(max(snr_dbm)/10)*10;
|
||||
min_snr = floor(min(snr_dbm)/10)*10;
|
||||
ylim([min_snr,max_snr]);
|
||||
yticks(-200:10:100);
|
||||
y_min = min(snr_dbm(:));
|
||||
y_max = max(snr_dbm(:));
|
||||
y_range = y_max - y_min;
|
||||
if y_range == 0
|
||||
y_range = 10;
|
||||
end
|
||||
y_margin = 0.05 * y_range;
|
||||
ylim([y_min - y_margin, y_max + y_margin]);
|
||||
try
|
||||
yticks(round(linspace(y_min, y_max, min(10, max(4, ceil(y_range/10))))));
|
||||
end
|
||||
|
||||
grid on; grid minor;
|
||||
legend('Interpreter','none');
|
||||
title('Noise of soft decision signal (not MLSE)');
|
||||
grid on;
|
||||
if isempty(get(gca, 'Legend'))
|
||||
legend('Interpreter','none');
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ arguments
|
||||
fs
|
||||
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.color = [];
|
||||
end
|
||||
|
||||
% Assuming that obj.e contains the final FFE filter coefficients.
|
||||
@@ -34,20 +35,24 @@ end
|
||||
end
|
||||
|
||||
% Magnitude response (in dB)
|
||||
subplot(2,1,1);
|
||||
% subplot(2,1,1);
|
||||
hold on
|
||||
plot(f.*1e-9, H_db,'DisplayName',options.displayname);
|
||||
if isempty(options.color)
|
||||
plot(f.*1e-9, H_db,'DisplayName',options.displayname,'LineWidth',1);
|
||||
else
|
||||
plot(f.*1e-9, H_db,'DisplayName',options.displayname,'Color',options.color,'LineWidth',1);
|
||||
end
|
||||
title('(Inverted) Magnitude Response of FFE Filter');
|
||||
xlabel('Frequency (GHz)');
|
||||
ylabel('Magnitude (dB)');
|
||||
grid on;
|
||||
|
||||
% Phase response
|
||||
subplot(2,1,2);
|
||||
plot(f.*1e-9, unwrap(angle(H)),'DisplayName',options.displayname);
|
||||
title('Phase Response of FFE Filter');
|
||||
xlabel('Frequency (GHz)');
|
||||
ylabel('Phase');
|
||||
grid on;
|
||||
% % Phase response
|
||||
% subplot(2,1,2);
|
||||
% plot(f.*1e-9, unwrap(angle(H)),'DisplayName',options.displayname);
|
||||
% title('Phase Response of FFE Filter');
|
||||
% xlabel('Frequency (GHz)');
|
||||
% ylabel('Phase');
|
||||
% grid on;
|
||||
|
||||
end
|
||||
@@ -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
|
||||
|
||||
|
||||
35
Functions/EQ_visuals/showMarkovDiagram.m
Normal file
35
Functions/EQ_visuals/showMarkovDiagram.m
Normal file
@@ -0,0 +1,35 @@
|
||||
function showMarkovDiagram(sequence,M)
|
||||
|
||||
|
||||
if isa(sequence,'Signal')
|
||||
sequence = sequence.signal;
|
||||
end
|
||||
sequence = sequence(2+mod(1,length(sequence)):end); %filtered sequences often have one "old" sample at idx=1
|
||||
|
||||
x = sequence;
|
||||
|
||||
levels = sort(unique(x)).'; % or provide known 1x6 level values
|
||||
|
||||
[~,ix] = min(abs(x - levels),[],2);
|
||||
x = levels(ix);
|
||||
|
||||
K = numel(levels);
|
||||
% map to state indices 1..K
|
||||
[tf, idx] = ismember(x, levels);
|
||||
idx = idx(:);
|
||||
from = idx(1:end-1);
|
||||
to = idx(2:end);
|
||||
from = idx(1:2:end);
|
||||
to = idx(2:2:end);
|
||||
|
||||
% counts C(from,to)
|
||||
C = accumarray([from,to], 1, [K K], @sum, 0);
|
||||
% row-stochastic transition matrix P(to|from)
|
||||
rowSums = sum(C,2);
|
||||
P = C ./ max(rowSums,1);
|
||||
|
||||
mc = dtmc(P, 'StateNames', string(levels.*PAMmapper(M,0).get_scaling));
|
||||
figure('Name','Markov Graph (dtmc)');
|
||||
gp = graphplot(mc, 'ColorEdges',true, 'LabelEdges',true);
|
||||
|
||||
end
|
||||
40
Functions/EQ_visuals/showTransitionProbabilities.m
Normal file
40
Functions/EQ_visuals/showTransitionProbabilities.m
Normal file
@@ -0,0 +1,40 @@
|
||||
function showTransitionProbabilities(sequence)
|
||||
|
||||
|
||||
if isa(sequence,'Signal')
|
||||
sequence = sequence.signal;
|
||||
end
|
||||
|
||||
sequence = sequence(2+mod(1,length(sequence)):end); %filtered sequences often have one "old" sample at idx=1
|
||||
|
||||
x = sequence;
|
||||
levels = sort(unique(x)).'; % or provide known 1x6 level values
|
||||
|
||||
[~,ix] = min(abs(x - levels),[],2);
|
||||
x = levels(ix);
|
||||
|
||||
|
||||
K = numel(levels);
|
||||
% map to state indices 1..K
|
||||
[tf, idx] = ismember(x, levels);
|
||||
idx = idx(:);
|
||||
% from = idx(1:end-1);
|
||||
% to = idx(2:end);
|
||||
from = idx(1:2:end);
|
||||
to = idx(2:2:end);
|
||||
|
||||
% counts C(from,to)
|
||||
C = accumarray([from,to], 1, [K K], @sum, 0);
|
||||
% row-stochastic transition matrix P(to|from)
|
||||
rowSums = sum(C,2);
|
||||
P = C ./ max(rowSums,1);
|
||||
|
||||
%% 1) HEATMAP (which transitions are more probable?)
|
||||
figure('Name','Transition Probabilities (to | from)');
|
||||
h = heatmap(levels, levels, P, 'Colormap', parula, 'ColorbarVisible','on');
|
||||
colormap(gca,[[1,1,1];flip(cbrewer2('Spectral',100))]);clim([0,ceil(max(P(:))*10)/10]);
|
||||
h.XLabel = 'From state (level)';
|
||||
h.YLabel = 'To state (level)';
|
||||
h.Title = 'P(to | from)';
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user