diff --git a/sw/utility/simulations.py b/sw/utility/simulations.py index 2c1d618..ab8ebbf 100644 --- a/sw/utility/simulations.py +++ b/sw/utility/simulations.py @@ -1,9 +1,9 @@ """This file contains utility functions relating to tests and simulations of the decoders.""" - import numpy as np import typing from tqdm import tqdm +from timeit import default_timer from utility import noise @@ -18,7 +18,8 @@ def count_bit_errors(d: np.array, d_hat: np.array) -> int: return np.sum(d != d_hat) -def test_decoder(x: np.array, +def test_decoder(n: int, + k: int, decoder: typing.Any, SNRs: typing.Sequence[float] = np.linspace(1, 7, 7), target_frame_errors: int = 100, @@ -28,7 +29,8 @@ def test_decoder(x: np.array, This function assumes the all-zeros assumption holds. Progress is printed to stdout. - :param x: Codeword to be sent (Element of [0, 1]^n) + :param n: Length of a codeword of the used code (n_cols of the H-matrix) + :param k: Length of a dataword of the used code (n_rows of the H-matrix) :param decoder: Instance of the decoder to be tested :param SNRs: List of SNRs for which the BER should be calculated :param target_frame_errors: Number of frame errors after which to stop the simulation @@ -36,11 +38,13 @@ def test_decoder(x: np.array, :return: Tuple of numpy arrays of the form (SNRs, BERs) """ + x = np.zeros(n) x_bpsk = 1 - 2 * x # Map x from [0, 1]^n to [-1, 1]^n BERs = [] - for SNR in tqdm(SNRs, desc="Calculating Bit-Error-Rates", - position=0, + for SNR in tqdm(SNRs, + desc=f"Calculating BERs for {decoder.__class__.__name__}", + position=1, leave=False, bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"): @@ -48,8 +52,9 @@ def test_decoder(x: np.array, total_bits = 0 total_frame_errors = 0 - for n in tqdm(range(N_max), desc=f"Simulating for SNR = {SNR} dB", - position=1, + for n in tqdm(range(N_max), + desc=f"Simulating for SNR = {SNR} dB", + position=2, leave=False, bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"): @@ -70,3 +75,40 @@ def test_decoder(x: np.array, BERs.append(total_bit_errors / total_bits) return np.array(SNRs), np.array(BERs) + + +def test_decoders(n: int, + k: int, + decoders: typing.List, + SNRs: typing.Sequence[float] = np.linspace(1, 7, 7), + target_frame_errors: int = 100, + N_max: int = 10000) \ + -> typing.Tuple[np.array, np.array]: + """Calculate the Bit Error Rate (BER) for a number of given decoders for a number of SNRs. + + This function assumes the all-zeros assumption holds. Progress is printed to stdout. + + :param n: Length of a codeword of the used code (n_cols of the H-matrix) + :param k: Length of a dataword of the used code (n_rows of the H-matrix) + :param decoders: List of decoder objects to be tested + :param SNRs: List of SNRs for which the BER should be calculated + :param target_frame_errors: Number of frame errors after which to stop the simulation + :param N_max: Maximum number of iterations to perform for each SNR + :return: Tuple of the form (SNRs, [BERs_1, BERs_2, ...]) where SNR and BERs_x are numpy arrays + """ + result_BERs = [] + + start_time = default_timer() + + for decoder in tqdm(decoders, + desc="Calculating the answer to life, the universe and everything", + position=0, + leave=False, + bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"): + _, BERs = test_decoder(n, k, decoder, SNRs, target_frame_errors, N_max) + result_BERs.append(BERs) + + end_time = default_timer() + print(f"Elapsed time: {end_time - start_time:.2f}s") + + return SNRs, result_BERs