Files
2026-03-24 17:23:02 +01:00

85 lines
3.1 KiB
Matlab

classdef MLSE_test < IMDDTestCase
methods (Test, TestTags = {'unit', 'fast', 'dsp', 'mlse'})
function constructorStoresConfiguration(testCase)
mlse = MLSE( ...
"M", 4, ...
"DIR", [1 0.35], ...
"trellis_states", [-3 -1 1 3], ...
"duobinary_output", false, ...
"trellis_state_mode", 2, ...
"trellis_exclusion", 0, ...
"scale_mode", 0, ...
"debug", 0);
testCase.verifyEqual(mlse.M, 4);
testCase.verifyEqual(mlse.DIR, [1 0.35]);
testCase.verifyEqual(mlse.trellis_states, [-3 -1 1 3]);
testCase.verifyFalse(mlse.duobinary_output);
testCase.verifyEqual(mlse.trellis_state_mode, 2);
testCase.verifyEqual(mlse.trellis_exclusion, 0);
testCase.verifyEqual(mlse.scale_mode, 0);
testCase.verifyEqual(mlse.debug, 0);
end
function processRecoversKnownPAM4Sequence(testCase)
[txBits, txSymbols, rxSymbols, mlse] = makePam4Fixture();
txSignal = Informationsignal(txSymbols, "fs", 1);
rxSignal = Signal(rxSymbols, "fs", 1);
hdSignal = mlse.process(rxSignal, txSignal);
rxBits = PAMmapper(4, 0).demap(hdSignal);
testCase.verifyClass(hdSignal, "Signal");
testCase.verifyEqual(hdSignal.fs, rxSignal.fs);
testCase.verifyEqual(rxBits.signal, txBits, ...
"MLSE should recover the transmitted PAM-4 bits on the deterministic fixture.");
end
function processReturnsExpectedShapesAndFiniteMetric(testCase)
[txBits, txSymbols, rxSymbols, mlse] = makePam4Fixture();
[viterbiSymbols, llr, gmi] = mlse.process_(rxSymbols, txSymbols);
rxBits = PAMmapper(4, 0).demap(viterbiSymbols(:));
expectedSymbols = txSymbols(:) ./ rms(txSymbols(:));
testCase.verifyEqual(numel(viterbiSymbols), numel(rxSymbols));
testCase.verifyEqual(size(llr), [numel(rxSymbols), 2]);
testCase.verifyTrue(isfinite(gmi));
testCase.verifyEqual(viterbiSymbols(:), expectedSymbols, "AbsTol", 1e-12);
testCase.verifyEqual(rxBits, txBits, ...
"Lower-level MLSE output should decode the same deterministic fixture.");
end
end
end
function [txBits, txSymbols, rxSymbols, mlse] = makePam4Fixture()
txBits = [ ...
0 0; ...
0 1; ...
1 1; ...
1 0; ...
0 1; ...
1 0; ...
0 0; ...
1 1];
mapper = PAMmapper(4, 0);
txSignal = Informationsignal(txBits);
txSymbols = mapper.map(txSignal).signal;
channel = [1 0.35];
rxSymbols = filter(channel, 1, txSymbols);
rxSymbols = rxSymbols + 0.01 * [0; 1; -1; 2; -2; 1; -1; 0];
mlse = MLSE( ...
"M", 4, ...
"DIR", channel, ...
"trellis_states", mapper.levels, ...
"duobinary_output", false, ...
"trellis_state_mode", 2, ...
"trellis_exclusion", 0, ...
"scale_mode", 0, ...
"debug", 0);
end