diff options
author | Johannes Demel <ufcsy@student.kit.edu> | 2015-10-12 17:00:00 +0200 |
---|---|---|
committer | Johannes Demel <ufcsy@student.kit.edu> | 2015-12-07 11:00:14 +0100 |
commit | f6c8d3fb95169ac8d8b443f75ce092864ec327e9 (patch) | |
tree | 984c6053f59333f94d54ed3b4b75fa6b443d9e0e /gr-fec | |
parent | d55fde354f257a1dd615a66c4ca98e3b6c6a5854 (diff) |
polar: systematic test code added
Diffstat (limited to 'gr-fec')
-rw-r--r-- | gr-fec/python/fec/polar/common.py | 15 | ||||
-rw-r--r-- | gr-fec/python/fec/polar/decoder.py | 75 | ||||
-rw-r--r-- | gr-fec/python/fec/polar/encoder.py | 40 | ||||
-rwxr-xr-x | gr-fec/python/fec/polar/testbed.py | 49 |
4 files changed, 113 insertions, 66 deletions
diff --git a/gr-fec/python/fec/polar/common.py b/gr-fec/python/fec/polar/common.py index b4b152de61..fa5987b6d2 100644 --- a/gr-fec/python/fec/polar/common.py +++ b/gr-fec/python/fec/polar/common.py @@ -65,5 +65,20 @@ class PolarCommon: def _vector_bit_reversed(self, vec, n): return bit_reverse_vector(vec, n) + def _encode_efficient(self, vec): + n_stages = self.power + pos = np.arange(self.N, dtype=int) + for i in range(n_stages): + splitted = np.reshape(pos, (2 ** (i + 1), -1)) + upper_branch = splitted[0::2].flatten() + lower_branch = splitted[1::2].flatten() + vec[upper_branch] = (vec[upper_branch] + vec[lower_branch]) % 2 + return vec + + def _encode_natural_order(self, vec): + # use this function. It reflects the encoding process implemented in VOLK. + vec = vec[self.bit_reverse_positions] + return self._encode_efficient(vec) + def info_print(self): print "POLAR code ({0}, {1})".format(self.N, self.K) diff --git a/gr-fec/python/fec/polar/decoder.py b/gr-fec/python/fec/polar/decoder.py index 10eef9b6ed..458858e16d 100644 --- a/gr-fec/python/fec/polar/decoder.py +++ b/gr-fec/python/fec/polar/decoder.py @@ -202,6 +202,33 @@ class PolarDecoder(PolarCommon): data = np.packbits(data) return data + def _extract_info_bits_reversed(self, y): + info_bit_positions_reversed = self._vector_bit_reversed(self.info_bit_position, self.power) + return y[info_bit_positions_reversed] + + def decode_systematic(self, data): + if not len(data) == self.N: + raise ValueError("len(data)={0} is not equal to n={1}!".format(len(data), self.N)) + # data = self._reverse_bits(data) + data = self._lr_sc_decoder_efficient(data) + data = self._encode_natural_order(data) + data = self._extract_info_bits_reversed(data) + return data + + +def test_systematic_decoder(): + ntests = 1000 + n = 16 + k = 8 + frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) + encoder = PolarEncoder(n, k, frozenbitposition) + decoder = PolarDecoder(n, k, frozenbitposition) + for i in range(ntests): + bits = np.random.randint(2, size=k) + y = encoder.encode_systematic(bits) + u_hat = decoder.decode_systematic(y) + assert (bits == u_hat).all() + def test_reverse_enc_dec(): n = 16 @@ -240,29 +267,31 @@ def compare_decoder_impls(): def main(): - power = 3 - n = 2 ** power - k = 4 - frozenbits = np.zeros(n - k, dtype=int) - frozenbitposition = np.array((0, 1, 2, 4), dtype=int) - frozenbitposition4 = np.array((0, 1), dtype=int) - - - encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) - decoder = PolarDecoder(n, k, frozenbitposition, frozenbits) - - bits = np.ones(k, dtype=int) - print "bits: ", bits - evec = encoder.encode(bits) - print "froz: ", encoder._insert_frozen_bits(bits) - print "evec: ", evec - - evec[1] = 0 - deced = decoder._lr_sc_decoder(evec) - print 'SC decoded:', deced - - test_reverse_enc_dec() - compare_decoder_impls() + # power = 3 + # n = 2 ** power + # k = 4 + # frozenbits = np.zeros(n - k, dtype=int) + # frozenbitposition = np.array((0, 1, 2, 4), dtype=int) + # frozenbitposition4 = np.array((0, 1), dtype=int) + # + # + # encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) + # decoder = PolarDecoder(n, k, frozenbitposition, frozenbits) + # + # bits = np.ones(k, dtype=int) + # print "bits: ", bits + # evec = encoder.encode(bits) + # print "froz: ", encoder._insert_frozen_bits(bits) + # print "evec: ", evec + # + # evec[1] = 0 + # deced = decoder._lr_sc_decoder(evec) + # print 'SC decoded:', deced + # + # test_reverse_enc_dec() + # compare_decoder_impls() + + test_systematic_decoder() if __name__ == '__main__': diff --git a/gr-fec/python/fec/polar/encoder.py b/gr-fec/python/fec/polar/encoder.py index 3b5eea2a94..cc8fda2d1b 100644 --- a/gr-fec/python/fec/polar/encoder.py +++ b/gr-fec/python/fec/polar/encoder.py @@ -41,16 +41,6 @@ class PolarEncoder(PolarCommon): data = data.astype(dtype=int) return data - def _encode_efficient(self, vec): - n_stages = int(np.log2(self.N)) - pos = np.arange(self.N, dtype=int) - for i in range(n_stages): - splitted = np.reshape(pos, (2 ** (i + 1), -1)) - upper_branch = splitted[0::2].flatten() - lower_branch = splitted[1::2].flatten() - vec[upper_branch] = (vec[upper_branch] + vec[lower_branch]) % 2 - return vec - def encode(self, data, is_packed=False): if not len(data) == self.K: raise ValueError("len(data)={0} is not equal to k={1}!".format(len(data), self.K)) @@ -64,6 +54,31 @@ class PolarEncoder(PolarCommon): data = np.packbits(data) return data + def encode_systematic(self, data): + if not len(data) == self.K: + raise ValueError("len(data)={0} is not equal to k={1}!".format(len(data), self.K)) + if np.max(data) > 1 or np.min(data) < 0: + raise ValueError("can only encode bits!") + + d = self._insert_frozen_bits(data) + d = self._encode_natural_order(d) + d = self._reverse_bits(d) + d[self.frozen_bit_position] = 0 + d = self._encode_natural_order(d) + # d = self._reverse_bits(d) # for more accuracy, do another bit-reversal. or don't for computational simplicity. + return d + + +def test_systematic_encoder(encoder, ntests, k): + for n in range(ntests): + bits = np.random.randint(2, size=k) + x = encoder.encode_systematic(bits) + x = encoder._reverse_bits(x) + u_hat = encoder._extract_info_bits(x) + + assert (bits == u_hat).all() + # print((bits == u_hat).all()) + def compare_results(encoder, ntests, k): for n in range(ntests): @@ -95,15 +110,16 @@ def test_encoder_impls(): ntests = 1000 n = 16 k = 8 - frozenbits = np.zeros(n - k) + # frozenbits = np.zeros(n - k) # frozenbitposition8 = np.array((0, 1, 2, 4), dtype=int) # keep it! frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) - encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) + encoder = PolarEncoder(n, k, frozenbitposition) #, frozenbits) print 'result:', compare_results(encoder, ntests, k) print('Test rate-1 encoder/decoder chain results') r1_test = test_pseudo_rate_1_encoder(encoder, ntests, k) print 'Test rate-1 encoder/decoder:', r1_test + test_systematic_encoder(encoder, ntests, k) def main(): diff --git a/gr-fec/python/fec/polar/testbed.py b/gr-fec/python/fec/polar/testbed.py index d60c83e776..3f8e814e4f 100755 --- a/gr-fec/python/fec/polar/testbed.py +++ b/gr-fec/python/fec/polar/testbed.py @@ -305,17 +305,19 @@ def find_decoder_subframes(frozen_mask): print('{0:4} lock {1:4} value: {2} in sub {3}'.format(i, 2 ** (l + 1), v, t)) -def load_file(filename): - z_params = [] - with open(filename, 'r') as f: - for line in f: - if 'Bhattacharyya:' in line: - l = line.split(' ') - l = l[10:-2] - l = l[0][:-1] - l = float(l) - z_params.append(l) - return np.array(z_params) +def systematic_encoder_decoder_chain_test(): + print('systematic encoder decoder chain test') + block_size = int(2 ** 8) + info_bit_size = block_size // 2 + ntests = 100 + frozenbitposition = cc.get_frozen_bit_indices_from_z_parameters(cc.bhattacharyya_bounds(0.0, block_size), block_size - info_bit_size) + encoder = PolarEncoder(block_size, info_bit_size, frozenbitposition) + decoder = PolarDecoder(block_size, info_bit_size, frozenbitposition) + for i in range(ntests): + bits = np.random.randint(2, size=info_bit_size) + y = encoder.encode_systematic(bits) + u_hat = decoder.decode_systematic(y) + assert (bits == u_hat).all() def main(): @@ -334,27 +336,12 @@ def main(): # test_1024_rate_1_code() # channel_analysis() - frozen_indices = cc.get_bec_frozen_indices(m, n_frozen, 0.11) - frozen_mask = cc.get_frozen_bit_mask(frozen_indices, m) - find_decoder_subframes(frozen_mask) - - frozen_mask = np.zeros(m, dtype=int) - frozen_mask[frozen_indices] = 1 + # frozen_indices = cc.get_bec_frozen_indices(m, n_frozen, 0.11) + # frozen_mask = cc.get_frozen_bit_mask(frozen_indices, m) + # find_decoder_subframes(frozen_mask) - # filename = 'channel_z-parameters.txt' - # ido = load_file(filename) - # ido_frozen = cc.get_frozen_bit_indices_from_z_parameters(ido, k) - # ido_mask = np.zeros(m, dtype=int) - # ido_mask[ido_frozen] = 1 - # - # - # plt.plot(ido_mask) - # plt.plot(frozen_mask) - # for i in range(m): - # if not ido_mask[i] == frozen_mask[i]: - # plt.axvline(i, color='r') - # plt.show() + systematic_encoder_decoder_chain_test() if __name__ == '__main__': - main()
\ No newline at end of file + main() |