Changed test_decoder() to get n and k as arguments; Reimplemented test_decoders() in utility.simulations

This commit is contained in:
Andreas Tsouchlos 2022-11-10 11:21:39 +01:00
parent a6baad0201
commit df94fb33b6

View File

@ -1,9 +1,9 @@
"""This file contains utility functions relating to tests and simulations of the decoders.""" """This file contains utility functions relating to tests and simulations of the decoders."""
import numpy as np import numpy as np
import typing import typing
from tqdm import tqdm from tqdm import tqdm
from timeit import default_timer
from utility import noise 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) return np.sum(d != d_hat)
def test_decoder(x: np.array, def test_decoder(n: int,
k: int,
decoder: typing.Any, decoder: typing.Any,
SNRs: typing.Sequence[float] = np.linspace(1, 7, 7), SNRs: typing.Sequence[float] = np.linspace(1, 7, 7),
target_frame_errors: int = 100, 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. 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 decoder: Instance of the decoder to be tested
:param SNRs: List of SNRs for which the BER should be calculated :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 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) :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 x_bpsk = 1 - 2 * x # Map x from [0, 1]^n to [-1, 1]^n
BERs = [] BERs = []
for SNR in tqdm(SNRs, desc="Calculating Bit-Error-Rates", for SNR in tqdm(SNRs,
position=0, desc=f"Calculating BERs for {decoder.__class__.__name__}",
position=1,
leave=False, leave=False,
bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"): bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"):
@ -48,8 +52,9 @@ def test_decoder(x: np.array,
total_bits = 0 total_bits = 0
total_frame_errors = 0 total_frame_errors = 0
for n in tqdm(range(N_max), desc=f"Simulating for SNR = {SNR} dB", for n in tqdm(range(N_max),
position=1, desc=f"Simulating for SNR = {SNR} dB",
position=2,
leave=False, leave=False,
bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt}"): 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) BERs.append(total_bit_errors / total_bits)
return np.array(SNRs), np.array(BERs) 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