Ordnerstruktur

This commit is contained in:
Silas Oettinghaus
2026-04-23 16:16:58 +02:00
parent 8fd68c0a54
commit 456fd02186
13 changed files with 1117 additions and 194 deletions

View File

@@ -21,21 +21,22 @@ classdef Signalgenerator
% "dimension", 2, ...
% "randkey", 3).process();
%
% % PRMS bit matrix for PAM-4 mapping. If length is omitted, the
% % output length is derived from order, as in the old PAMsource.
% % PRMS bit matrix for PAM-4 mapping. M selects the mapper-ready bit
% % shape. If length is omitted, the output length is derived from
% % order, as in the old PAMsource.
% bits = Signalgenerator( ...
% "form", signalform.prms, ...
% "dimension", 2, ...
% "M", 4, ...
% "order", 7).process();
% symbols = PAMmapper(4, 0).map(bits);
%
% % PRMS for PAM-6: 5 bits map to 2 PAM-6 symbols
% % PRMS for PAM-6: 5 bits map to 2 PAM-6 symbols. M = 6 returns
% % the 1-D bit vector expected by PAMmapper.
% bits = Signalgenerator( ...
% "form", signalform.prms, ...
% "dimension", 5, ...
% "M", 6, ...
% "order", 7).process();
% bitVector = reshape(bits.signal.', [], 1);
% symbols = PAMmapper(6, 0).map(bitVector);
% symbols = PAMmapper(6, 0).map(bits);
%
% % Map, demap, and check BER
% mapper = PAMmapper(8, 0);
@@ -54,6 +55,7 @@ classdef Signalgenerator
fs
fsig
dimension
M
order
randkey
skip
@@ -72,6 +74,7 @@ classdef Signalgenerator
options.fs double = 1000 %Hz sampling
options.fsig double = 50 % Hz fundamental frex e.g. of the sine or sawtooth
options.dimension double = 1
options.M double = []
options.order double = 7
options.randkey double = 0
options.skip double = 0
@@ -86,6 +89,11 @@ classdef Signalgenerator
end
end
if ~isempty(obj.M)
obj.validate_pam_format();
obj.dimension = obj.mapper_bit_dimension();
end
if isempty(obj.length)
obj.length = obj.default_length();
end
@@ -136,7 +144,8 @@ classdef Signalgenerator
case signalform.prms
signal = obj.build_prms_data();
end
signal = obj.format_for_mapper(signal);
end
@@ -169,12 +178,15 @@ classdef Signalgenerator
% PAM-8: dimension = 3
%
% PAM-6 is special in this codebase: the mapper consumes 5 bits and
% maps them to two PAM-6 symbols. Use dimension = 5, then flatten
% the output before calling PAMmapper(6, ...).map(...).
% maps them to two PAM-6 symbols. Prefer M = 6 to generate the 1-D
% vector expected by PAMmapper(6, ...).map(...). The legacy
% dimension = 5 path still returns the unflattened bit matrix.
%
% Relevant Signalgenerator options:
% length Number of generated PRMS bit groups / rows.
% dimension Number of parallel bit streams per row.
% M Optional PAM format. When set, dimension is selected
% automatically and PAM-6 output is mapper-ready.
% order User-facing sequence order, matching the old
% PAMsource behavior. If length is omitted, it sets the
% output length. Internally it is converted to the PRMS
@@ -252,10 +264,17 @@ classdef Signalgenerator
end
end
function validate_pam_format(obj)
if ~ismember(obj.M, [2 4 6 8 16])
error("Signalgenerator:InvalidPAMFormat", ...
"M must be one of 2, 4, 6, 8, or 16.");
end
end
function length = default_length(obj)
switch obj.form
case {signalform.random, signalform.prms}
if obj.dimension == 5
if obj.is_pam6_shape()
length = 2^max(0, obj.order - 2);
else
length = 2^max(0, obj.order - 1);
@@ -266,7 +285,9 @@ classdef Signalgenerator
end
function prms_order = internal_prms_order(obj)
if obj.dimension == 5
if ~isempty(obj.M)
bits_per_symbol = log2(obj.M);
elseif obj.dimension == 5
bits_per_symbol = log2(6);
else
bits_per_symbol = obj.dimension;
@@ -275,6 +296,25 @@ classdef Signalgenerator
prms_order = max(1, floor(obj.order / bits_per_symbol));
end
function dimension = mapper_bit_dimension(obj)
if obj.M == 6
dimension = 5;
else
dimension = log2(obj.M);
end
end
function tf = is_pam6_shape(obj)
tf = (~isempty(obj.M) && obj.M == 6) || (isempty(obj.M) && obj.dimension == 5);
end
function signal = format_for_mapper(obj, signal)
if ~isempty(obj.M) && obj.M == 6
signal = reshape(signal.', [], 1);
signal = signal(1:end - mod(numel(signal), 5));
end
end
end