def test_equalize_data(self): num_of_subcarriers = 24 ofdm_obj = OFDM(num_of_subcarriers, cp_size=8) onetap_equalizer = ofdm.OfdmOneTapEqualizer(ofdm_obj) qam_obj = fundamental.QAM(4) # Input data data = np.random.randint(0, 4, size=2 * num_of_subcarriers) # Modulate with QAM symbols = qam_obj.modulate(data) # Modulate with OFDM transmit_data = ofdm_obj.modulate(symbols) # xxxxxxxxxx Channel Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Calculate the actual bandwidth that we will use bandwidth = 55e3 * num_of_subcarriers Fd = 50 # Doppler frequency (in Hz) Ts = 1. / bandwidth # Sampling interval (in seconds) NRays = 16 # Number of rays for the Jakes model jakes = fading_generators.JakesSampleGenerator(Fd, Ts, NRays, shape=None) tdlchannel = fading.TdlChannel( jakes, tap_powers_dB=fading.COST259_TUx.tap_powers_dB, tap_delays=fading.COST259_TUx.tap_delays) channel_memory = tdlchannel.num_taps_with_padding - 1 # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Pass the signal through the channel xxxxxxxxxxxxxxxxxx received_signal = tdlchannel.corrupt_data(transmit_data) # Impulse response used to transmit the signal last_impulse_response = tdlchannel.get_last_impulse_response() # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx OFDM Reception xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Demodulate with OFDM received_demodulated_data = ofdm_obj.demodulate( received_signal[:-channel_memory]) received_equalized_data = onetap_equalizer.equalize_data( received_demodulated_data, last_impulse_response) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Demodulation and testing xxxxxxxxxxxxxxxxxxxxxxxxxxxxx demodulated_received_data = qam_obj.demodulate(received_equalized_data) np.testing.assert_array_equal(data, demodulated_received_data)
def test_equalize_data(self): num_of_subcarriers = 24 ofdm_obj = OFDM(num_of_subcarriers, cp_size=8) onetap_equalizer = ofdm.OfdmOneTapEqualizer(ofdm_obj) qam_obj = fundamental.QAM(4) # Input data data = np.random.randint(0, 4, size=2*num_of_subcarriers) # Modulate with QAM symbols = qam_obj.modulate(data) # Modulate with OFDM transmit_data = ofdm_obj.modulate(symbols) # xxxxxxxxxx Channel Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Calculate the actual bandwidth that we will use bandwidth = 55e3 * num_of_subcarriers Fd = 50 # Doppler frequency (in Hz) Ts = 1./bandwidth # Sampling interval (in seconds) NRays = 16 # Number of rays for the Jakes model jakes = fading_generators.JakesSampleGenerator( Fd, Ts, NRays, shape=None) tdlchannel = fading.TdlChannel( jakes, tap_powers_dB=fading.COST259_TUx.tap_powers_dB, tap_delays=fading.COST259_TUx.tap_delays) channel_memory = tdlchannel.num_taps_with_padding - 1 # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Pass the signal through the channel xxxxxxxxxxxxxxxxxx received_signal = tdlchannel.corrupt_data(transmit_data) # Impulse response used to transmit the signal last_impulse_response = tdlchannel.get_last_impulse_response() # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx OFDM Reception xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Demodulate with OFDM received_demodulated_data = ofdm_obj.demodulate( received_signal[:-channel_memory]) received_equalized_data = onetap_equalizer.equalize_data( received_demodulated_data, last_impulse_response) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Demodulation and testing xxxxxxxxxxxxxxxxxxxxxxxxxxxxx demodulated_received_data = qam_obj.demodulate(received_equalized_data) np.testing.assert_array_equal(data, demodulated_received_data)
# Jakes sample generator parameters Fd = 5 Ts = 2.0e-7 L = 20 # Channel Profile channel_profile = COST259_TUx.get_discretize_profile(Ts) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Input generation (not part of OFDM) xxxxxxxxxxxxxxxxxxxxxx # generate input data input_data = np.random.random_integers(0, 4 - 1, num_symbols) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx QPSK and OFDM Modulators xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx qpsk_obj = QPSK() ofdm_obj = OFDM(fft_size=fft_size, cp_size=cp_size, num_used_subcarriers=num_used_subcarriers) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Modulate data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx modulated_data = qpsk_obj.modulate(input_data) transmit_data = ofdm_obj.modulate(modulated_data) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx Transmit data through the channel xxxxxxxxxxxxxxxxxxxxxxxx jakes = JakesSampleGenerator(Fd, Ts, L) channel = SuChannel(jakes, channel_profile) channel_memory = channel.num_taps_with_padding - 1 received_data = channel.corrupt_data(transmit_data) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxx OFDM Demodulate data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
def setUp(self): """Called before each test.""" self.ofdm_object = OFDM(64, 16, 52)
class OfdmTestCase(unittest.TestCase): """Unittests for the OFDM class in the ofdm module.""" def setUp(self): """Called before each test.""" self.ofdm_object = OFDM(64, 16, 52) def test_ofdm_set_parameters(self): # Test regular usage self.assertEqual(self.ofdm_object.fft_size, 64) self.assertEqual(self.ofdm_object.cp_size, 16) self.assertEqual(self.ofdm_object.num_used_subcarriers, 52) self.ofdm_object.set_parameters(128, 32, 100) self.assertEqual(self.ofdm_object.fft_size, 128) self.assertEqual(self.ofdm_object.cp_size, 32) self.assertEqual(self.ofdm_object.num_used_subcarriers, 100) # Test if an exception is raised when any invalid parameters are # passed to set_parameters # Raises an exception if number of used subcarriers is odd with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, 16, 51) # Raises an exception if number of used subcarriers is greater than # the fft_size with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, 16, 70) # Raises an exception if cp_size is negative with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, -2, 52) # Raises an exception if cp_size is greater than the fft_size with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, 65, 52) # Test if the number of subcarriers defaults to the fft_size when # not provided self.ofdm_object.set_parameters(64, 16) self.assertEqual(self.ofdm_object.num_used_subcarriers, 64) def test_prepare_input_signal(self, ): # 52 elements -> exactly the number of used subcarriers in the OFDM # object input_signal = np.r_[1:53] # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Lets first test the case where we use exactly 52 subcarriers from # the 64 available subcarriers. That is, no zeropadding is needed. (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad( input_signal.size) self.assertEqual(zeropad, 0) self.assertEqual(num_ofdm_symbols, 1) expected_data = np.array( [[0., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.]]) np.testing.assert_array_equal( self.ofdm_object._prepare_input_signal(input_signal), expected_data) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Now lets change the number of used subcarriers and repeat the # tests so that the case when zeropad is performed is also tested. self.ofdm_object.num_used_subcarriers = 60 (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad( input_signal.size) # We used 60 subcarriers, but we have 52 elements -> We need to add # 8 zeros at the end of the unput data self.assertEqual(zeropad, 8) # But we still have only one OFDM symbol self.assertEqual(num_ofdm_symbols, 1) expected_data2 = np.array( [[0., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., ]]) np.testing.assert_array_equal( self.ofdm_object._prepare_input_signal(input_signal), expected_data2) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Now lets test the case when we use all subcarriers (but still # with zeropadding) self.ofdm_object.num_used_subcarriers = 64 (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad( input_signal.size) self.assertEqual(zeropad, 12) # But we still have only one OFDM symbol self.assertEqual(num_ofdm_symbols, 1) # Notice that in this case the DC subcarrier is used expected_data3 = np.array( [[33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32.]]) np.testing.assert_array_equal( self.ofdm_object._prepare_input_signal(input_signal), expected_data3) def test_prepare_decoded_signal(self): input1 = np.r_[1:105] input2 = self.ofdm_object._prepare_input_signal(input1) output = self.ofdm_object._prepare_decoded_signal(input2) np.testing.assert_array_equal(output, input1) def test_calculate_power_scale(self): expected_power_scale = float(self.ofdm_object.fft_size) \ * (float(self.ofdm_object.fft_size) / (self.ofdm_object.num_used_subcarriers + self.ofdm_object.cp_size)) self.assertAlmostEqual(expected_power_scale, self.ofdm_object._calculate_power_scale()) self.ofdm_object.fft_size = 1024. self.ofdm_object.cp_size = 100. self.ofdm_object.num_used_subcarriers = 900. self.assertAlmostEqual(1024. * (1024. / (900. + 100.)), self.ofdm_object._calculate_power_scale()) def test_modulate(self): # Exactly two OFDM symbols (with 52 used subcarriers) input_signal = np.r_[1:105] # xxxxx First lets try without cyclic prefix xxxxxxxxxxxxxxxxxxxxxx self.ofdm_object.set_parameters(64, 0, 52) (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad( input_signal.size) self.assertEqual(zeropad, 0) # But we still have only one OFDM symbol self.assertEqual(num_ofdm_symbols, 2) input_ifft = self.ofdm_object._prepare_input_signal(input_signal) power_scale = self.ofdm_object._calculate_power_scale() expected_data_no_power_scale = np.hstack([ np.fft.ifft(input_ifft[0, :]), np.fft.ifft(input_ifft[1, :]), ]) expected_data = math.sqrt(power_scale) * expected_data_no_power_scale np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal), expected_data) # Let's test each OFDM symbol individually np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal[0:52]), expected_data[0:64]) np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal[52:]), expected_data[64:]) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now lets test with a cyclic prefix xxxxxxxxxxxxxxxxxxxxxxxx self.ofdm_object.set_parameters(64, 4, 52) input_ifft2 = self.ofdm_object._prepare_input_signal(input_signal[0:52]) power_scale2 = self.ofdm_object._calculate_power_scale() expected_data_no_power_scale2 = np.hstack([ np.fft.ifft(input_ifft[0, :]), ]) expected_data2 = math.sqrt(power_scale2) * expected_data_no_power_scale2 expected_data2 = np.hstack( [expected_data2[-self.ofdm_object.cp_size:], expected_data2[0:64]]) np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal[0:52]), expected_data2) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx def test_demodulate(self): # xxxxx First lets try without cyclic prefix xxxxxxxxxxxxxxxxxxxxxx # Exactly two OFDM symbols (with 52 used subcarriers) input_signal = np.r_[1:105] + 1j * np.r_[1:105] # xxxxx First lets try without cyclic prefix xxxxxxxxxxxxxxxxxxxxxx self.ofdm_object.set_parameters(64, 0, 52) modulated_ofdm_symbols = self.ofdm_object.modulate(input_signal) demodulated_symbols = self.ofdm_object.demodulate( modulated_ofdm_symbols) np.testing.assert_array_equal( demodulated_symbols.round(), input_signal ) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now lets test with a cyclic prefix xxxxxxxxxxxxxxxxxxxxxxxx # Exactly two OFDM symbols (with 52 used subcarriers) input_signal2 = np.r_[1:105] + 1j * np.r_[1:105] self.ofdm_object.set_parameters(64, 16, 52) modulated_ofdm_symbols2 = self.ofdm_object.modulate(input_signal2) demodulated_symbols2 = self.ofdm_object.demodulate( modulated_ofdm_symbols2) np.testing.assert_array_equal( demodulated_symbols2.round(), input_signal2 ) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now lets test the case with zeropadding xxxxxxxxxxxxxxxxxxx # Exactly two OFDM symbols (with 52 used subcarriers) input_signal3 = np.r_[1:110]+1j * np.r_[1:110] self.ofdm_object.set_parameters(64, 16, 52) modulated_ofdm_symbols3 = self.ofdm_object.modulate(input_signal3) demodulated_symbols3 = self.ofdm_object.demodulate( modulated_ofdm_symbols3) # OFDM will not remove the zeropadding therefore we need to do it # manually demodulated_symbols3 = demodulated_symbols3[0:109] np.testing.assert_array_equal( demodulated_symbols3.round(), input_signal3 )
class OfdmTestCase(unittest.TestCase): """Unittests for the OFDM class in the ofdm module.""" def setUp(self): """Called before each test.""" self.ofdm_object = OFDM(64, 16, 52) def test_ofdm_set_parameters(self): # Test regular usage self.assertEqual(self.ofdm_object.fft_size, 64) self.assertEqual(self.ofdm_object.cp_size, 16) self.assertEqual(self.ofdm_object.num_used_subcarriers, 52) self.ofdm_object.set_parameters(128, 32, 100) self.assertEqual(self.ofdm_object.fft_size, 128) self.assertEqual(self.ofdm_object.cp_size, 32) self.assertEqual(self.ofdm_object.num_used_subcarriers, 100) # Test if an exception is raised when any invalid parameters are # passed to set_parameters # Raises an exception if number of used subcarriers is odd with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, 16, 51) # Raises an exception if number of used subcarriers is greater than # the fft_size with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, 16, 70) # Raises an exception if cp_size is negative with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, -2, 52) # Raises an exception if cp_size is greater than the fft_size with self.assertRaises(ValueError): self.ofdm_object.set_parameters(64, 65, 52) # Test if the number of subcarriers defaults to the fft_size when # not provided self.ofdm_object.set_parameters(64, 16) self.assertEqual(self.ofdm_object.num_used_subcarriers, 64) def test_prepare_input_signal(self, ): # 52 elements -> exactly the number of used subcarriers in the OFDM # object input_signal = np.r_[1:53] # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Lets first test the case where we use exactly 52 subcarriers from # the 64 available subcarriers. That is, no zeropadding is needed. (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad(input_signal.size) self.assertEqual(zeropad, 0) self.assertEqual(num_ofdm_symbols, 1) expected_data = np.array([[ 0., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26. ]]) np.testing.assert_array_equal( self.ofdm_object._prepare_input_signal(input_signal), expected_data) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Now lets change the number of used subcarriers and repeat the # tests so that the case when zeropad is performed is also tested. self.ofdm_object.num_used_subcarriers = 60 (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad(input_signal.size) # We used 60 subcarriers, but we have 52 elements -> We need to add # 8 zeros at the end of the input data self.assertEqual(zeropad, 8) # But we still have only one OFDM symbol self.assertEqual(num_ofdm_symbols, 1) expected_data2 = np.array([[ 0., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., ]]) np.testing.assert_array_equal( self.ofdm_object._prepare_input_signal(input_signal), expected_data2) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Now lets test the case when we use all subcarriers (but still # with zeropadding) self.ofdm_object.num_used_subcarriers = 64 (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad(input_signal.size) self.assertEqual(zeropad, 12) # But we still have only one OFDM symbol self.assertEqual(num_ofdm_symbols, 1) # Notice that in this case the DC subcarrier is used expected_data3 = np.array([[ 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32. ]]) np.testing.assert_array_equal( self.ofdm_object._prepare_input_signal(input_signal), expected_data3) def test_prepare_decoded_signal(self): input1 = np.r_[1:105] input2 = self.ofdm_object._prepare_input_signal(input1) output = self.ofdm_object._prepare_decoded_signal(input2) np.testing.assert_array_equal(output, input1) # noinspection PyPep8 def test_calculate_power_scale(self): expected_power_scale = float(self.ofdm_object.fft_size) \ * (float(self.ofdm_object.fft_size) / (self.ofdm_object.num_used_subcarriers + self.ofdm_object.cp_size)) self.assertAlmostEqual(expected_power_scale, self.ofdm_object._calculate_power_scale()) self.ofdm_object.fft_size = 1024. self.ofdm_object.cp_size = 100. self.ofdm_object.num_used_subcarriers = 900. self.assertAlmostEqual(1024. * (1024. / (900. + 100.)), self.ofdm_object._calculate_power_scale()) def test_modulate(self): # Exactly two OFDM symbols (with 52 used subcarriers) input_signal = np.r_[1:105] # xxxxx First lets try without cyclic prefix xxxxxxxxxxxxxxxxxxxxxx self.ofdm_object.set_parameters(64, 0, 52) (zeropad, num_ofdm_symbols) = self.ofdm_object._calc_zeropad(input_signal.size) self.assertEqual(zeropad, 0) # But we still have only one OFDM symbol self.assertEqual(num_ofdm_symbols, 2) input_ifft = self.ofdm_object._prepare_input_signal(input_signal) power_scale = self.ofdm_object._calculate_power_scale() expected_data_no_power_scale = np.hstack([ np.fft.ifft(input_ifft[0, :]), np.fft.ifft(input_ifft[1, :]), ]) expected_data = math.sqrt(power_scale) * expected_data_no_power_scale np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal), expected_data) # Let's test each OFDM symbol individually np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal[0:52]), expected_data[0:64]) np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal[52:]), expected_data[64:]) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now lets test with a cyclic prefix xxxxxxxxxxxxxxxxxxxxxxxx self.ofdm_object.set_parameters(64, 4, 52) # input_ifft2 = # self.ofdm_object._prepare_input_signal(input_signal[0:52]) power_scale2 = self.ofdm_object._calculate_power_scale() expected_data_no_power_scale2 = np.hstack([ np.fft.ifft(input_ifft[0, :]), ]) expected_data2 = math.sqrt( power_scale2) * expected_data_no_power_scale2 expected_data2 = np.hstack( [expected_data2[-self.ofdm_object.cp_size:], expected_data2[0:64]]) np.testing.assert_array_almost_equal( self.ofdm_object.modulate(input_signal[0:52]), expected_data2) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx def test_demodulate(self): # xxxxx First lets try without cyclic prefix xxxxxxxxxxxxxxxxxxxxxx # Exactly two OFDM symbols (with 52 used subcarriers) input_signal = np.r_[1:105] + 1j * np.r_[1:105] ":type: np.ndarray" # xxxxx First lets try without cyclic prefix xxxxxxxxxxxxxxxxxxxxxx self.ofdm_object.set_parameters(64, 0, 52) modulated_ofdm_symbols = self.ofdm_object.modulate(input_signal) demodulated_symbols = self.ofdm_object.demodulate( modulated_ofdm_symbols) np.testing.assert_array_equal(demodulated_symbols.round(), input_signal) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now lets test with a cyclic prefix xxxxxxxxxxxxxxxxxxxxxxxx # Exactly two OFDM symbols (with 52 used subcarriers) input_signal2 = np.r_[1:105] + 1j * np.r_[1:105] ":type: np.ndarray" self.ofdm_object.set_parameters(64, 16, 52) modulated_ofdm_symbols2 = self.ofdm_object.modulate(input_signal2) demodulated_symbols2 = self.ofdm_object.demodulate( modulated_ofdm_symbols2) np.testing.assert_array_equal(demodulated_symbols2.round(), input_signal2) # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # xxxxx Now lets test the case with zeropadding xxxxxxxxxxxxxxxxxxx # Exactly two OFDM symbols (with 52 used subcarriers) input_signal3 = np.r_[1:110] + 1j * np.r_[1:110] ":type: np.ndarray" self.ofdm_object.set_parameters(64, 16, 52) modulated_ofdm_symbols3 = self.ofdm_object.modulate(input_signal3) demodulated_symbols3 = self.ofdm_object.demodulate( modulated_ofdm_symbols3) # OFDM will not remove the zeropadding therefore we need to do it # manually demodulated_symbols3 = demodulated_symbols3[0:109] np.testing.assert_array_equal(demodulated_symbols3.round(), input_signal3)