classdef ML_MLSE_DUOBINARY_test < IMDDTestCase methods (Test, TestTags = {'unit', 'fast', 'dsp', 'ml_mlse', 'duobinary'}) function constructorStoresDuobinaryConfiguration(testCase) eq = ML_MLSE_DUOBINARY(); testCase.verifyEqual(class(eq), 'ML_MLSE_DUOBINARY'); testCase.verifyEqual(eq.sps, 2); testCase.verifyEqual(eq.order, 15); testCase.verifyEqual(eq.ber, []); testCase.verifyEqual(eq.ber_dd, []); end function processReturnsPrecodeDomainAndFiniteDiagnostics(testCase) [~, ~, txPrecoded, txEncoded] = makePam4Fixture(512); eq = ML_MLSE_DUOBINARY( ... "sps", 1, ... "order", 1, ... "len_tr", length(txEncoded), ... "epochs_tr", 1, ... "epochs_dd", 1, ... "mu_tr", 0.01, ... "mu_dd", 0.01, ... "adaptive_mu", false, ... "L", 1); [detected, detectedViterbi] = eq.process(txEncoded, txPrecoded); testCase.verifyEqual(length(detected), length(txEncoded)); testCase.verifyEqual(length(detectedViterbi), length(txEncoded)); testCase.verifyTrue(all(ismembertol(detected.signal, unique(txPrecoded.signal), 1e-12))); testCase.verifySize(eq.ber, [1 1]); testCase.verifySize(eq.ber_dd, [1 1]); testCase.verifyTrue(isfinite(eq.ber(1))); testCase.verifyTrue(isfinite(eq.ber_dd(1))); end function encodeDecodeInvertsPrecodingAwayFromInitialState(testCase) [~, txSymbols, txPrecoded, ~] = makePam4Fixture(512); encoded = Duobinary().encode(txPrecoded, "M", 4); decoded = Duobinary().decode(encoded, "M", 4); testCase.verifyEqual(decoded.signal(11:end-10), ... txSymbols.signal(11:end-10), "AbsTol", 1e-12); end function resultWrapperReportsBothPrecodedAndOriginalBer(testCase) [txBits, ~, txPrecoded, txEncoded] = makePam4Fixture(32000); eq = ML_MLSE_DUOBINARY( ... "sps", 1, ... "order", 1, ... "len_tr", length(txEncoded), ... "epochs_tr", 1, ... "epochs_dd", 1, ... "mu_tr", 0.01, ... "mu_dd", 0.01, ... "adaptive_mu", false, ... "L", 1); results = ml_mlse(eq, 4, txEncoded, txPrecoded, txBits, ... "precode_mode", db_mode.db_precoded); testCase.verifyTrue(isfinite(results.metrics.BER)); testCase.verifyTrue(isfinite(results.metrics.BER_precoded)); testCase.verifyGreaterThanOrEqual(results.metrics.numBits, 0); testCase.verifyGreaterThanOrEqual(results.metrics.numBitErr, 0); testCase.verifyGreaterThanOrEqual(results.metrics.numBitErr_precoded, 0); end end end function [txBits, txSymbols, txPrecoded, txEncoded] = makePam4Fixture(nSymbols) pattern = [0 0; 0 1; 1 1; 1 0]; bits = repmat(pattern, ceil(nSymbols / size(pattern, 1)), 1); bits = bits(1:nSymbols, :); txBits = Informationsignal(bits); txSymbols = PAMmapper(4, 0).map(txBits); txPrecoded = Duobinary().precode(txSymbols); txEncoded = Duobinary().encode(txPrecoded, "M", 4); end