Add PAMmapper bit mapping and Gray penalty visualization

This commit is contained in:
Silas Oettinghaus
2026-03-26 16:04:30 +01:00
parent c135cb76b1
commit 10a205f231
7 changed files with 180 additions and 36 deletions

View File

@@ -504,9 +504,118 @@ classdef PAMmapper
end
function bitmap = showBitMapping(obj)
function [ax, mapping_table] = plotBitMapping(obj)
[constellation, bitmap] = obj.getConstellationBitMapping();
constellation = constellation .* obj.get_scaling;
bit_labels = string(cellstr(char(bitmap + '0')));
bitmap = obj.demap((obj.levels ./ obj.scaling)');
if obj.M == 6
[~, order] = sortrows([-constellation(:,2), constellation(:,1)]);
constellation = constellation(order, :);
bit_labels = bit_labels(order);
mapping_table = table(constellation(:,1), constellation(:,2), bit_labels, ...
'VariableNames', {'symbol_1', 'symbol_2', 'bits'});
fig = figure("Name", sprintf("PAM-%d Bit Mapping", obj.M));
ax = axes(fig);
scatter(ax, constellation(:,1), constellation(:,2), 60, "filled");
hold(ax, "on");
grid(ax, "on");
box(ax, "on");
x_step = min(diff(unique(constellation(:,1))));
y_step = min(diff(unique(constellation(:,2))));
text(ax, constellation(:,1), constellation(:,2) + 0.18*y_step, bit_labels, ...
"HorizontalAlignment", "center", "FontName", "Consolas");
xlabel(ax, "Symbol 1");
ylabel(ax, "Symbol 2");
title(ax, sprintf("PAM-%d Mapping", obj.M));
axis(ax, "equal");
xticks(ax, unique(constellation(:,1)));
yticks(ax, unique(constellation(:,2)));
xlim(ax, [min(constellation(:,1)) - 0.8*x_step, max(constellation(:,1)) + 1.4*x_step]);
ylim(ax, [min(constellation(:,2)) - 0.6*y_step, max(constellation(:,2)) + 0.9*y_step]);
else
constellation = constellation(:);
mapping_table = table(constellation, bit_labels, ...
'VariableNames', {'symbol', 'bits'});
fig = figure("Name", sprintf("PAM-%d Bit Mapping", obj.M));
ax = axes(fig);
scatter(ax, constellation, zeros(size(constellation)), 60, "filled");
hold(ax, "on");
grid(ax, "on");
box(ax, "on");
text(ax, constellation, 0.08*ones(size(constellation)), bit_labels, ...
"HorizontalAlignment", "center", "FontName", "Consolas");
xlabel(ax, "Symbol");
title(ax, sprintf("PAM-%d Mapping", obj.M));
yticks(ax, []);
ylim(ax, [-0.2 0.2]);
xticks(ax, constellation);
if numel(constellation) > 1
x_step = min(diff(unique(constellation)));
else
x_step = 1;
end
xlim(ax, [min(constellation) - 0.8*x_step, max(constellation) + 0.8*x_step]);
end
if nargout == 0
disp(mapping_table);
end
end
function bitmap = showBitMapping(obj)
[~, bitmap] = obj.getConstellationBitMapping();
end
function [Gp, details] = graypenalty(obj)
[constellation, bit_labels] = obj.getConstellationBitMapping();
num_points = size(constellation, 1);
dist2 = inf(num_points);
for idx = 1:num_points
delta = constellation - constellation(idx, :);
dist2(idx, :) = sum(delta.^2, 2).';
end
dist2(1:num_points+1:end) = inf;
min_dist2 = min(dist2(:));
is_neighbor = abs(dist2 - min_dist2) < 1e-12;
hamming_dist = zeros(num_points);
for idx = 1:num_points
hamming_dist(idx, :) = sum(bit_labels ~= bit_labels(idx, :), 2).';
end
Gp = sum(hamming_dist(is_neighbor)) / nnz(is_neighbor);
if nargout > 1
details = struct( ...
"constellation", constellation, ...
"bit_labels", bit_labels, ...
"neighbor_mask", is_neighbor, ...
"nearest_distance", sqrt(min_dist2));
end
end
function [constellation, bitmap] = getConstellationBitMapping(obj)
if obj.M == 6
constellation = obj.thresholds ./ obj.scaling;
bitmap = obj.demap(reshape(constellation.', [], 1));
bitmap = reshape(bitmap, 5, []).';
else
constellation = (obj.levels ./ obj.scaling)';
bitmap = obj.demap(constellation);
end
end