def test_triang_ldpc_systematic_encode(self): ldpc_design_files = (os.path.join(self.dir, '../designs/ldpc/wimax/1440.720.txt'), os.path.join(self.dir, '../designs/ldpc/wimax/960.720.a.txt')) wimax_ldpc_params = [get_ldpc_code_params(ldpc_design_file) for ldpc_design_file in ldpc_design_files] for param in wimax_ldpc_params: # Test padding with assert_raises(ValueError): triang_ldpc_systematic_encode(choice((0, 1), 2), param, False) triang_ldpc_systematic_encode(choice((0, 1), 720), param, False) # Test encoding message_bits = choice((0, 1), 1450) coded_bits = triang_ldpc_systematic_encode(message_bits, param) syndrome = param['parity_check_matrix'].dot(coded_bits).reshape(-1) % 2 assert_allclose(syndrome, zeros_like(syndrome), err_msg='Coded message is not in the code book.') # Test decoding coded_bits[coded_bits == 1] = -1 coded_bits[coded_bits == 0] = 1 MSA_decoded_bits = ldpc_bp_decode(coded_bits.reshape(-1, order='F').astype(float), param, 'MSA', 10)[0] SPA_decoded_bits = ldpc_bp_decode(coded_bits.reshape(-1, order='F').astype(float), param, 'SPA', 10)[0] # Extract systematic part MSA_decoded_bits = MSA_decoded_bits[:720].reshape(-1, order='F') SPA_decoded_bits = SPA_decoded_bits[:720].reshape(-1, order='F') assert_equal(MSA_decoded_bits[:len(message_bits)], message_bits, 'Encoded and decoded messages do not match the initial bits without noise (MS algorithm)') assert_equal(SPA_decoded_bits[:len(message_bits)], message_bits, 'Encoded and decoded messages do not match the initial bits without noise (SP algorithm)')
def test_write_ldpc_params(self): with TemporaryDirectory() as tmp_dir: parity_check_matrix = choice((0, 1), (720, 1440)) file_path = tmp_dir + '/matrix.txt' write_ldpc_params(parity_check_matrix, file_path) assert_equal(get_ldpc_code_params(file_path, True)['parity_check_matrix'].toarray(), parity_check_matrix, 'The loaded matrix is not equal to the written one.')
def test_ldpc_bp_decode(self): ldpc_design_file = os.path.join( self.dir, '../designs/ldpc/gallager/96.33.964.txt') ldpc_code_params = get_ldpc_code_params(ldpc_design_file) for n_blocks in (1, 2): N = 96 * n_blocks rate = 0.5 Es = 1.0 snr_list = array([2.0, 2.5]) niters = 10000000 tx_codeword = zeros(N, int) ldpcbp_iters = 100 for decoder_algorithm in ('MSA', 'SPA'): fer_array_ref = array((.2, .1)) fer_array_test = zeros(len(snr_list)) for idx, ebno in enumerate(snr_list): noise_std = 1 / sqrt((10**(ebno / 10.0)) * rate * 2 / Es) fer_cnt_bp = 0 for iter_cnt in range(niters): awgn_array = noise_std * randn(N) rx_word = 1 - (2 * tx_codeword) + awgn_array rx_llrs = 2.0 * rx_word / (noise_std**2) [dec_word, _] = ldpc_bp_decode(rx_llrs, ldpc_code_params, decoder_algorithm, ldpcbp_iters) if hamming_dist(tx_codeword, dec_word.reshape(-1)): fer_cnt_bp += 1 if fer_cnt_bp >= 50: fer_array_test[idx] = float(fer_cnt_bp) / ( iter_cnt + 1) / n_blocks break assert_allclose(fer_array_test, fer_array_ref, rtol=.6, atol=0, err_msg=decoder_algorithm + ' algorithm does not perform as expected.')
def test_ldpc_bp_decode(self): ldpc_design_file = os.path.join( self.dir, '../designs/ldpc/gallager/96.33.964.txt') ldpc_code_params = get_ldpc_code_params(ldpc_design_file) for n_blocks in (1, 2): N = 96 * n_blocks rate = 0.5 Es = 1.0 snr_list = array([2.0, 2.5]) niters = 10000000 tx_codeword = zeros(N, int) ldpcbp_iters = 100 fer_array_ref = array([200.0 / 1000, 200.0 / 2000]) fer_array_test = zeros(len(snr_list)) for idx, ebno in enumerate(snr_list): noise_std = 1 / sqrt((10**(ebno / 10.0)) * rate * 2 / Es) fer_cnt_bp = 0 for iter_cnt in range(niters): awgn_array = noise_std * randn(N) rx_word = 1 - (2 * tx_codeword) + awgn_array rx_llrs = 2.0 * rx_word / (noise_std**2) [dec_word, out_llrs] = ldpc_bp_decode(rx_llrs, ldpc_code_params, 'SPA', ldpcbp_iters) num_bit_errors = hamming_dist(tx_codeword, dec_word.reshape(-1)) if num_bit_errors > 0: fer_cnt_bp += 1 if fer_cnt_bp >= 200: fer_array_test[idx] = float(fer_cnt_bp) / ( iter_cnt + 1) / n_blocks break assert_allclose(fer_array_test, fer_array_ref, rtol=.5, atol=0)
def setup_class(cls): dir = os.path.dirname(__file__) ldpc_design_file_1 = os.path.join(dir, '../designs/ldpc/gallager/96.33.964.txt') #ldpc_design_file_1 = "../designs/ldpc/gallager/96.33.964.txt" cls.ldpc_code_params = get_ldpc_code_params(ldpc_design_file_1)
from numpy import array, sqrt, zeros from numpy.random import randn from numpy.testing import assert_allclose from commpy.channelcoding.ldpc import get_ldpc_code_params, ldpc_bp_decode from commpy.utilities import hamming_dist import os from nose.plugins.attrib import attr if __name__ == '__main__': dir = os.path.dirname(__file__) ldpc_design_file_1 = os.path.join( dir, './channelcoding//designs/ldpc/gallager/96.33.964.txt') #ldpc_design_file_1 = "../designs/ldpc/gallager/96.33.964.txt" ldpc_code_params = get_ldpc_code_params(ldpc_design_file_1) N = 96 k = 48 rate = 0.5 Es = 1.0 snr_list = array([2.0, 2.5]) niters = 10000000 tx_codeword = zeros(N, int) ldpcbp_iters = 100 fer_array_ref = array([200.0 / 1000, 200.0 / 2000]) fer_array_test = zeros(len(snr_list)) for idx, ebno in enumerate(snr_list):
def test_link_performance(): # Set seed seed(8071996) ###################################### # Build models & desired solutions ###################################### models = [] desired_bers = [] snr_range = [] labels = [] rtols = [] code_rates = [] # SISO QPSK and AWGN channel QPSK = QAMModem(4) def receiver(y, h, constellation, noise_var): return QPSK.demodulate(y, 'hard') models.append( LinkModel(QPSK.modulate, SISOFlatChannel(fading_param=(1 + 0j, 0)), receiver, QPSK.num_bits_symbol, QPSK.constellation, QPSK.Es)) snr_range.append(arange(0, 9, 2)) desired_bers.append(erfc(sqrt(10**(snr_range[-1] / 10) / 2)) / 2) labels.append('SISO QPSK and AWGN channel') rtols.append(.25) code_rates.append(1) # MIMO 16QAM, 4x4 Rayleigh channel and hard-output K-Best QAM16 = QAMModem(16) RayleighChannel = MIMOFlatChannel(4, 4) RayleighChannel.uncorr_rayleigh_fading(complex) def receiver(y, h, constellation, noise_var): return QAM16.demodulate(kbest(y, h, constellation, 16), 'hard') models.append( LinkModel(QAM16.modulate, RayleighChannel, receiver, QAM16.num_bits_symbol, QAM16.constellation, QAM16.Es)) snr_range.append(arange(0, 21, 5) + 10 * log10(QAM16.num_bits_symbol)) desired_bers.append((2e-1, 1e-1, 3e-2, 2e-3, 4e-5)) # From reference labels.append('MIMO 16QAM, 4x4 Rayleigh channel and hard-output K-Best') rtols.append(1.25) code_rates.append(1) # MIMO 16QAM, 4x4 Rayleigh channel and soft-output best-first QAM16 = QAMModem(16) RayleighChannel = MIMOFlatChannel(4, 4) RayleighChannel.uncorr_rayleigh_fading(complex) ldpc_params = get_ldpc_code_params( 'commpy/channelcoding/designs/ldpc/wimax/1440.720.txt', True) def modulate(bits): return QAM16.modulate( triang_ldpc_systematic_encode(bits, ldpc_params, False).reshape(-1, order='F')) def decoder(llrs): return ldpc_bp_decode(llrs, ldpc_params, 'MSA', 15)[0][:720].reshape(-1, order='F') def demode(symbs): return QAM16.demodulate(symbs, 'hard') def receiver(y, h, constellation, noise_var): return best_first_detector(y, h, constellation, (1, 3, 5), noise_var, demode, 500) models.append( LinkModel(modulate, RayleighChannel, receiver, QAM16.num_bits_symbol, QAM16.constellation, QAM16.Es, decoder, 0.5)) snr_range.append(arange(17, 20, 1)) desired_bers.append((1.7e-1, 1e-1, 2.5e-3)) # From reference labels.append( 'MIMO 16QAM, 4x4 Rayleigh channel and soft-output best-first') rtols.append(2) code_rates.append(.5) ###################################### # Make tests ###################################### for test in range(len(models)): BERs = link_performance(models[test], snr_range[test], 5e5, 200, 720, models[test].rate) assert_allclose(BERs, desired_bers[test], rtol=rtols[test], err_msg='Wrong performance for ' + labels[test]) full_metrics = models[test].link_performance_full_metrics( snr_range[test], 2500, 200, 720, models[test].rate) assert_allclose(full_metrics[0], desired_bers[test], rtol=rtols[test], err_msg='Wrong performance for ' + labels[test])
def setup_class(cls): dir = os.path.dirname(__file__) ldpc_design_file_1 = os.path.join( dir, '../designs/ldpc/gallager/96.33.964.txt') #ldpc_design_file_1 = "../designs/ldpc/gallager/96.33.964.txt" cls.ldpc_code_params = get_ldpc_code_params(ldpc_design_file_1)