summaryrefslogtreecommitdiff
path: root/gr-fec/python
diff options
context:
space:
mode:
authorJohannes Demel <ufcsy@student.kit.edu>2015-12-01 10:47:30 +0100
committerJohannes Demel <ufcsy@student.kit.edu>2015-12-01 10:53:41 +0100
commitf32185874396775d8137c3d2a7662da0121cec47 (patch)
tree62d6408319a8d3d2ef2913e73137569d322c75b6 /gr-fec/python
parent3fb49b6d3887b2b7fbeb1bbda674b509f0b37d56 (diff)
polar: BEC channel construction optimized
Conflicts: gr-fec/python/fec/polar/channel_construction_bec.py
Diffstat (limited to 'gr-fec/python')
-rw-r--r--gr-fec/python/fec/polar/channel_construction_bec.py155
1 files changed, 137 insertions, 18 deletions
diff --git a/gr-fec/python/fec/polar/channel_construction_bec.py b/gr-fec/python/fec/polar/channel_construction_bec.py
index f8f960dfe7..4b35602d96 100644
--- a/gr-fec/python/fec/polar/channel_construction_bec.py
+++ b/gr-fec/python/fec/polar/channel_construction_bec.py
@@ -51,22 +51,45 @@ def calc_one_recursion(iw0):
return iw1
+def calculate_bec_channel_capacities_loop(initial_channel, block_power):
+ # compare [0, Arikan] eq. 6
+ iw = np.array([initial_channel, ], dtype=float)
+ for i in range(block_power):
+ iw = calc_one_recursion(iw)
+ return iw
+
+
+def calc_vector_capacities_one_recursion(iw0):
+ degraded = odd_rec(iw0)
+ upgraded = even_rec(iw0)
+ iw1 = np.empty(2 * len(iw0), dtype=degraded.dtype)
+ iw1[0::2] = degraded
+ iw1[1::2] = upgraded
+ return iw1
+
+
+def calculate_bec_channel_capacities_vector(initial_channel, block_power):
+ # compare [0, Arikan] eq. 6
+ # this version is ~ 180 times faster than the loop version with 2**22 synthetic channels
+ iw = np.array([initial_channel, ], dtype=float)
+ for i in range(block_power):
+ iw = calc_vector_capacities_one_recursion(iw)
+ return iw
+
+
def calculate_bec_channel_capacities(eta, block_size):
# compare [0, Arikan] eq. 6
iw = 1 - eta # holds for BEC as stated in paper
- iw = np.array([iw, ], dtype=float)
lw = hf.power_of_2_int(block_size)
- for i in range(lw):
- iw = calc_one_recursion(iw)
- return iw
+ return calculate_bec_channel_capacities_vector(iw, lw)
def calculate_z_parameters_one_recursion(z_params):
- z_next = np.zeros(2 * z_params.size)
- for i in range(z_params.size):
- z_sq = z_params[i] ** 2
- z_next[2 * i] = 2 * z_params[i] - z_sq
- z_next[2 * i + 1] = z_sq
+ z_next = np.empty(2 * z_params.size, dtype=z_params.dtype)
+ z_sq = z_params ** 2
+ z_low = 2 * z_params - z_sq
+ z_next[0::2] = z_low
+ z_next[1::2] = z_sq
return z_next
@@ -80,6 +103,7 @@ def calculate_bec_channel_z_parameters(eta, block_size):
def design_snr_to_bec_eta(design_snr):
+ # minimum design snr = -1.5917 corresponds to BER = 0.5
s = 10. ** (design_snr / 10.)
return np.exp(-s)
@@ -95,21 +119,116 @@ def bhattacharyya_bounds(design_snr, block_size):
For BEC that translates to capacity(i) = 1 - bhattacharyya(i)
:return Z-parameters in natural bit-order. Choose according to desired rate.
'''
- # minimum design snr = -1.5917 corresponds to BER = 0.5
- s = 10 ** (design_snr / 10) # 'initial z parameter'.
- eta = np.exp(-s)
+ eta = design_snr_to_bec_eta(design_snr)
return calculate_bec_channel_z_parameters(eta, block_size)
+def plot_channel_capacities(capacity, save_file=None):
+ block_size = len(capacity)
+ try:
+ import matplotlib.pyplot as plt
+ # FUN with matplotlib LaTeX fonts! http://matplotlib.org/users/usetex.html
+ plt.rc('text', usetex=True)
+ plt.rc('font', family='serif')
+ plt.rc('figure', autolayout=True)
+ plt.plot(capacity)
+ plt.xlim([0, block_size])
+ plt.ylim([-0.01, 1.01])
+ plt.xlabel('synthetic channel number')
+ plt.ylabel('channel capacity')
+ # plt.title('BEC channel construction')
+ plt.grid()
+ plt.gcf().set_size_inches(plt.gcf().get_size_inches() * .5)
+ if save_file:
+ plt.savefig(save_file)
+ plt.show()
+ except ImportError:
+ pass # only plot in case matplotlib is installed
+
+
+def plot_average_channel_distance(save_file=None):
+ eta = 0.5 # design_snr_to_bec_eta(-1.5917)
+ powers = np.arange(4, 26)
+
+ try:
+ import matplotlib.pyplot as plt
+ import matplotlib
+ # FUN with matplotlib LaTeX fonts! http://matplotlib.org/users/usetex.html
+ plt.rc('text', usetex=True)
+ plt.rc('font', family='serif')
+ plt.rc('figure', autolayout=True)
+
+ dist = []
+ medians = []
+ initial_channel = 1 - eta
+ for p in powers:
+ bs = int(2 ** p)
+ capacities = calculate_bec_channel_capacities(eta, bs)
+ avg_capacity = np.repeat(initial_channel, len(capacities))
+ averages = np.abs(capacities - avg_capacity)
+ avg_distance = np.sum(averages) / float(len(capacities))
+ dist.append(avg_distance)
+ variance = np.std(averages)
+ medians.append(variance)
+
+ plt.errorbar(powers, dist, yerr=medians)
+ plt.grid()
+ plt.xlabel(r'block size $N$')
+ plt.ylabel(r'$\frac{1}{N} \sum_i |I(W_N^{(i)}) - 0.5|$')
+
+ axes = plt.axes()
+ tick_values = np.array(axes.get_xticks().tolist())
+ tick_labels = np.array(tick_values, dtype=int)
+ tick_labels = ['$2^{' + str(i) + '}$' for i in tick_labels]
+ plt.xticks(tick_values, tick_labels)
+ plt.xlim((powers[0], powers[-1]))
+ plt.ylim((0.2, 0.5001))
+ plt.gcf().set_size_inches(plt.gcf().get_size_inches() * .5)
+ if save_file:
+ plt.savefig(save_file)
+ plt.show()
+ except ImportError:
+ pass
+
+
+def plot_capacity_histogram(design_snr, save_file=None):
+ eta = design_snr_to_bec_eta(design_snr)
+ # capacities = calculate_bec_channel_capacities(eta, block_size)
+ try:
+ import matplotlib.pyplot as plt
+ # FUN with matplotlib LaTeX fonts! http://matplotlib.org/users/usetex.html
+ plt.rc('text', usetex=True)
+ plt.rc('font', family='serif')
+ plt.rc('figure', autolayout=True)
+
+ block_sizes = [32, 128, 512]
+ for b in block_sizes:
+ capacities = calculate_bec_channel_capacities(eta, b)
+ w = 1. / float(len(capacities))
+ weights = [w, ] * b
+ plt.hist(capacities, bins=b, weights=weights, range=(0.95, 1.0))
+ plt.grid()
+ plt.xlabel('synthetic channel capacity')
+ plt.ylabel('normalized item count')
+ print(plt.gcf().get_size_inches())
+ plt.gcf().set_size_inches(plt.gcf().get_size_inches() * .5)
+ if save_file:
+ plt.savefig(save_file)
+ plt.show()
+ except ImportError:
+ pass
+
+
def main():
print 'channel construction main'
- n = 10
- block_size = 2 ** n
- design_snr = 1.0
+ n = 11
+ block_size = int(2 ** n)
+ design_snr = -1.59
eta = design_snr_to_bec_eta(design_snr)
- print(calculate_bec_channel_z_parameters(eta, block_size))
- print(calculate_bec_channel_capacities(eta, block_size))
-
+ # print(calculate_bec_channel_z_parameters(eta, block_size))
+ # capacity = calculate_bec_channel_capacities(eta, block_size)
+ # plot_average_channel_distance()
+ calculate_bec_channel_z_parameters(eta, block_size)
if __name__ == '__main__':
main()