classdef PAMsource_test < IMDDTestCase methods (Test, TestTags = {'unit', 'fast', 'transmit', 'pamsource'}) function constructorStoresProvidedOptions(testCase) src = PAMsource( ... "order", 5, ... "useprbs", false, ... "M", 4, ... "fsym", 8, ... "randkey", 17, ... "applypulseform", false, ... "fs_out", 8, ... "applyclipping", false); testCase.verifyEqual(src.order, 5); testCase.verifyFalse(src.useprbs); testCase.verifyEqual(src.M, 4); testCase.verifyEqual(src.fsym, 8); testCase.verifyEqual(src.randkey, 17); testCase.verifyFalse(src.applypulseform); testCase.verifyEqual(src.fs_out, 8); testCase.verifyFalse(src.applyclipping); testCase.verifyEmpty(src.pulseformer); end function deterministicProcessMatchesPamMapperAcrossOrders(testCase) orders = [2, 4, 8]; sourceOrder = 5; fs = 8; seed = 17; for M = orders src = PAMsource( ... "order", sourceOrder, ... "useprbs", false, ... "M", M, ... "fsym", fs, ... "randkey", seed, ... "applypulseform", false, ... "fs_out", fs, ... "applyclipping", false); [digiSig, symbols, bits] = src.process(); bitpattern = expectedBitpattern(M, sourceOrder, seed); expectedBits = Informationsignal(bitpattern); expectedSymbols = PAMmapper(M, 0).map(expectedBits); testCase.verifyClass(digiSig, 'Informationsignal'); testCase.verifyClass(symbols, 'Informationsignal'); testCase.verifyClass(bits, 'Informationsignal'); testCase.verifyEqual(bits.signal, bitpattern); testCase.verifyEqual(symbols.signal, expectedSymbols.signal); testCase.verifyEqual(digiSig.signal, expectedSymbols.signal); testCase.verifyEqual(digiSig.fs, fs); end end function clippingLimitsAmplitudeToScaledConstellationRange(testCase) M = 4; sourceOrder = 5; fs = 8; seed = 3; src = PAMsource( ... "order", sourceOrder, ... "useprbs", false, ... "M", M, ... "fsym", fs, ... "randkey", seed, ... "applypulseform", false, ... "fs_out", fs, ... "applyclipping", true, ... "clipfactor", 0.5); [digiSig, symbols, bits] = src.process(); expectedBits = expectedBitpattern(M, sourceOrder, seed); expectedSymbols = PAMmapper(M, 0).map(Informationsignal(expectedBits)); lowerLimit = min(expectedSymbols.signal) * 0.5; upperLimit = max(expectedSymbols.signal) * 0.5; expectedClipped = expectedSymbols.signal; expectedClipped(expectedClipped < lowerLimit) = lowerLimit; expectedClipped(expectedClipped > upperLimit) = upperLimit; testCase.verifyEqual(bits.signal, expectedBits); testCase.verifyEqual(symbols.signal, expectedSymbols.signal); testCase.verifyEqual(digiSig.signal, expectedClipped); testCase.verifyEqual(digiSig.fs, fs); testCase.verifyLessThanOrEqual(max(digiSig.signal), upperLimit); testCase.verifyGreaterThanOrEqual(min(digiSig.signal), lowerLimit); end end end function bitpattern = expectedBitpattern(M, order, seed) bitWidth = log2(M); N = 2^(order - 1); s = RandStream('twister', 'Seed', seed); bitpattern = zeros(N, bitWidth); for idx = 1:bitWidth bitpattern(:, idx) = randi(s, [0 1], N, 1); end end