Module polarcodes.AWGN
This class simulates an AWGN channel by adding gaussian noise with double-sided noise power.
It updates likelihoods
in PolarCode
with randomly generated log-likelihood ratios
for u
in PolarCode
. For puncturing, the likelihoods for the punctured bits given by
source_set_lookup
in PolarCode
will be set to zero. For shortening,
these likelihoods will be set to infinity. Currently only BPSK modulation is supported.
Expand source code
#!/usr/bin/env python
"""
This class simulates an AWGN channel by adding gaussian noise with double-sided noise power.
It updates ``likelihoods`` in `PolarCode` with randomly generated log-likelihood ratios
for ``u`` in `PolarCode`. For puncturing, the likelihoods for the punctured bits given by
``source_set_lookup`` in `PolarCode` will be set to zero. For shortening,
these likelihoods will be set to infinity. Currently only BPSK modulation is supported.
"""
import matplotlib.pyplot as plt
import numpy as np
class AWGN:
def __init__(self, myPC, Eb_No, plot_noise = False):
"""
Parameters
----------
myPC: `PolarCode`
a polar code object created using the `PolarCode` class
Eb_No: float
the design SNR in decibels
plot_noise: bool
a flag to view the modeled noise
"""
self.myPC = myPC
self.Es = myPC.get_normalised_SNR(Eb_No)
self.No = 1
self.plot_noise = plot_noise
tx = self.modulation(self.myPC.u)
rx = tx + self.noise(self.myPC.N)
self.myPC.likelihoods = np.array(self.get_likelihoods(rx), dtype=np.float64)
# change shortened/punctured bit LLRs
if self.myPC.punct_flag:
if self.myPC.punct_type == 'shorten':
self.myPC.likelihoods[self.myPC.source_set_lookup == 0] = np.inf
elif self.myPC.punct_type == 'punct':
self.myPC.likelihoods[self.myPC.source_set_lookup == 0] = 0
def LLR(self, y):
"""
> Finds the log-likelihood ratio of a received signal.
LLR = Pr(y=0)/Pr(y=1).
Parameters
----------
y: float
a received signal from a gaussian-distributed channel
Returns
----------
float
log-likelihood ratio for the input signal ``y``
"""
return -2 * y * np.sqrt(self.Es) / self.No
def get_likelihoods(self, y):
"""
Finds the log-likelihood ratio of an ensemble of received signals using :func:`LLR`.
Parameters
----------
y: ndarray<float>
an ensemble of received signals
Returns
----------
ndarray<float>
log-likelihood ratios for the input signals ``y``
"""
return [self.LLR(y[i]) for i in range(len(y))]
def modulation(self, x):
"""
BPSK modulation for a bit field.
"1" maps to +sqrt(E_s) and "0" maps to -sqrt(E_s).
Parameters
----------
x: ndarray<int>
an ensemble of information to send
Returns
----------
ndarray<float>
modulated signal with the information from ``x``
"""
return 2 * (x - 0.5) * np.sqrt(self.Es)
def noise(self, N):
"""
Generate gaussian noise with a specified noise power.
For a noise power N_o, the double-side noise power is N_o/2.
Parameters
----------
N: float
the noise power
Returns
----------
ndarray<float>
white gaussian noise vector
"""
# gaussian RNG vector
s = np.random.normal(0, np.sqrt(self.No / 2), size=N)
# display RNG values with ideal gaussian pdf
if self.plot_noise:
num_bins = 1000
count, bins, ignored = plt.hist(s, num_bins, density=True)
plt.plot(bins, 1 / (np.sqrt(np.pi * self.No)) * np.exp(- (bins) ** 2 / self.No),
linewidth=2, color='r')
plt.title('AWGN')
plt.xlabel('Noise, n')
plt.ylabel('Density')
plt.legend(['Theoretical', 'RNG'])
plt.draw()
return s
def show_noise(self):
"""
Trigger showing the gaussian noise. Only works if ``plot_noise`` is True.
"""
plt.show()
Classes
class AWGN (myPC, Eb_No, plot_noise=False)
-
Parameters
myPC
:PolarCode
- a polar code object created using the
PolarCode
class Eb_No
:float
- the design SNR in decibels
plot_noise
:bool
- a flag to view the modeled noise
Expand source code
class AWGN: def __init__(self, myPC, Eb_No, plot_noise = False): """ Parameters ---------- myPC: `PolarCode` a polar code object created using the `PolarCode` class Eb_No: float the design SNR in decibels plot_noise: bool a flag to view the modeled noise """ self.myPC = myPC self.Es = myPC.get_normalised_SNR(Eb_No) self.No = 1 self.plot_noise = plot_noise tx = self.modulation(self.myPC.u) rx = tx + self.noise(self.myPC.N) self.myPC.likelihoods = np.array(self.get_likelihoods(rx), dtype=np.float64) # change shortened/punctured bit LLRs if self.myPC.punct_flag: if self.myPC.punct_type == 'shorten': self.myPC.likelihoods[self.myPC.source_set_lookup == 0] = np.inf elif self.myPC.punct_type == 'punct': self.myPC.likelihoods[self.myPC.source_set_lookup == 0] = 0 def LLR(self, y): """ > Finds the log-likelihood ratio of a received signal. LLR = Pr(y=0)/Pr(y=1). Parameters ---------- y: float a received signal from a gaussian-distributed channel Returns ---------- float log-likelihood ratio for the input signal ``y`` """ return -2 * y * np.sqrt(self.Es) / self.No def get_likelihoods(self, y): """ Finds the log-likelihood ratio of an ensemble of received signals using :func:`LLR`. Parameters ---------- y: ndarray<float> an ensemble of received signals Returns ---------- ndarray<float> log-likelihood ratios for the input signals ``y`` """ return [self.LLR(y[i]) for i in range(len(y))] def modulation(self, x): """ BPSK modulation for a bit field. "1" maps to +sqrt(E_s) and "0" maps to -sqrt(E_s). Parameters ---------- x: ndarray<int> an ensemble of information to send Returns ---------- ndarray<float> modulated signal with the information from ``x`` """ return 2 * (x - 0.5) * np.sqrt(self.Es) def noise(self, N): """ Generate gaussian noise with a specified noise power. For a noise power N_o, the double-side noise power is N_o/2. Parameters ---------- N: float the noise power Returns ---------- ndarray<float> white gaussian noise vector """ # gaussian RNG vector s = np.random.normal(0, np.sqrt(self.No / 2), size=N) # display RNG values with ideal gaussian pdf if self.plot_noise: num_bins = 1000 count, bins, ignored = plt.hist(s, num_bins, density=True) plt.plot(bins, 1 / (np.sqrt(np.pi * self.No)) * np.exp(- (bins) ** 2 / self.No), linewidth=2, color='r') plt.title('AWGN') plt.xlabel('Noise, n') plt.ylabel('Density') plt.legend(['Theoretical', 'RNG']) plt.draw() return s def show_noise(self): """ Trigger showing the gaussian noise. Only works if ``plot_noise`` is True. """ plt.show()
Methods
def LLR(self, y)
-
Finds the log-likelihood ratio of a received signal. LLR = Pr(y=0)/Pr(y=1).
Parameters
y
:float
- a received signal from a gaussian-distributed channel
Returns
float
- log-likelihood ratio for the input signal
y
Expand source code
def LLR(self, y): """ > Finds the log-likelihood ratio of a received signal. LLR = Pr(y=0)/Pr(y=1). Parameters ---------- y: float a received signal from a gaussian-distributed channel Returns ---------- float log-likelihood ratio for the input signal ``y`` """ return -2 * y * np.sqrt(self.Es) / self.No
def get_likelihoods(self, y)
-
Finds the log-likelihood ratio of an ensemble of received signals using :func:
LLR
.Parameters
y
:ndarray<float>
- an ensemble of received signals
Returns
ndarray<float>
- log-likelihood ratios for the input signals
y
Expand source code
def get_likelihoods(self, y): """ Finds the log-likelihood ratio of an ensemble of received signals using :func:`LLR`. Parameters ---------- y: ndarray<float> an ensemble of received signals Returns ---------- ndarray<float> log-likelihood ratios for the input signals ``y`` """ return [self.LLR(y[i]) for i in range(len(y))]
def modulation(self, x)
-
BPSK modulation for a bit field. "1" maps to +sqrt(E_s) and "0" maps to -sqrt(E_s).
Parameters
x
:ndarray<int>
- an ensemble of information to send
Returns
ndarray<float>
- modulated signal with the information from
x
Expand source code
def modulation(self, x): """ BPSK modulation for a bit field. "1" maps to +sqrt(E_s) and "0" maps to -sqrt(E_s). Parameters ---------- x: ndarray<int> an ensemble of information to send Returns ---------- ndarray<float> modulated signal with the information from ``x`` """ return 2 * (x - 0.5) * np.sqrt(self.Es)
def noise(self, N)
-
Generate gaussian noise with a specified noise power. For a noise power N_o, the double-side noise power is N_o/2.
Parameters
N
:float
- the noise power
Returns
ndarray<float>
- white gaussian noise vector
Expand source code
def noise(self, N): """ Generate gaussian noise with a specified noise power. For a noise power N_o, the double-side noise power is N_o/2. Parameters ---------- N: float the noise power Returns ---------- ndarray<float> white gaussian noise vector """ # gaussian RNG vector s = np.random.normal(0, np.sqrt(self.No / 2), size=N) # display RNG values with ideal gaussian pdf if self.plot_noise: num_bins = 1000 count, bins, ignored = plt.hist(s, num_bins, density=True) plt.plot(bins, 1 / (np.sqrt(np.pi * self.No)) * np.exp(- (bins) ** 2 / self.No), linewidth=2, color='r') plt.title('AWGN') plt.xlabel('Noise, n') plt.ylabel('Density') plt.legend(['Theoretical', 'RNG']) plt.draw() return s
def show_noise(self)
-
Trigger showing the gaussian noise. Only works if
plot_noise
is True.Expand source code
def show_noise(self): """ Trigger showing the gaussian noise. Only works if ``plot_noise`` is True. """ plt.show()