Skip to content

Commit cc070ac

Browse files
committed
Move basic files
1 parent 4c1a92b commit cc070ac

File tree

8 files changed

+107
-16
lines changed

8 files changed

+107
-16
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .codec import BasePolarCodec, BasePolarCodeWithCRC
2+
from .decoder import BaseDecoder
3+
from .functions import *
4+
from .decoding_path import DecodingPathMixin

python_polar_coding/polar_codes/base/polar_code.py renamed to python_polar_coding/polar_codes/base/codec.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44

55
import numpy as np
66

7-
from . import crc, encoder, pcc, utils
7+
from . import encoder
8+
from python_polar_coding.polar_codes import utils, crc, pcc
89

910

10-
class BasicPolarCode(metaclass=abc.ABCMeta):
11-
"""Basic Polar code class.
11+
class BasePolarCodec(metaclass=abc.ABCMeta):
12+
"""Basic codec for Polar code.
1213
1314
Includes code construction.
14-
Provides the basic workflow for encoding and decoding.
15+
Defines the basic workflow for encoding and decoding.
1516
1617
Supports creation of a polar code from custom mask.
1718
@@ -47,8 +48,8 @@ def __init__(self, N: int, K: int,
4748
N=self.N, n=self.n, design_snr=design_snr, pcc_method=pcc_method)
4849
self.mask = self._polar_code_construction(mask)
4950

50-
self.encoder = self.get_encoder()
51-
self.decoder = self.get_decoder()
51+
self.encoder = self.init_encoder()
52+
self.decoder = self.init_decoder()
5253

5354
def __str__(self):
5455
return (f'({self.N}, {self.K}) Polar code.\n'
@@ -67,13 +68,13 @@ def to_dict(self):
6768
'mask': ''.join(str(m) for m in self.mask),
6869
}
6970

70-
def get_encoder(self):
71+
def init_encoder(self):
7172
"""Get Polar Encoder instance."""
7273
return self.encoder_class(mask=self.mask, n=self.n,
7374
is_systematic=self.is_systematic)
7475

7576
@abc.abstractmethod
76-
def get_decoder(self):
77+
def init_decoder(self):
7778
"""Get Polar Decoder instance."""
7879

7980
def encode(self, message: np.array) -> np.array:
@@ -132,7 +133,7 @@ def _construct_polar_mask(self, K):
132133
return np.array([m[2] for m in mask])
133134

134135

135-
class BasicPolarCodeWithCRC(BasicPolarCode):
136+
class BasePolarCodeWithCRC(BasePolarCodec):
136137
"""Basic Polar code class with CRC support.
137138
138139
Provides the support of CRC 16 and CRC 32.
@@ -145,7 +146,7 @@ def __init__(self, N: int, K: int,
145146
is_systematic: bool = True,
146147
crc_size: int = 32,
147148
mask: Union[str, None] = None,
148-
pcc_method: str = BasicPolarCode.BHATTACHARYYA):
149+
pcc_method: str = BasePolarCodec.BHATTACHARYYA):
149150

150151
assert crc_size in [16, 32], f'Unsupported CRC size ({crc_size})'
151152
assert K + crc_size < N, (f'Cannot create Polar code with N = {N},'
@@ -167,7 +168,7 @@ def to_dict(self):
167168
d.update({'crc_size': self.crc_size})
168169
return d
169170

170-
def get_encoder(self):
171+
def init_encoder(self):
171172
"""Get Polar Encoder instance."""
172173
return self.encoder_class(mask=self.mask, n=self.n,
173174
is_systematic=self.is_systematic,
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
from copy import deepcopy
2+
3+
import numpy as np
4+
5+
6+
class DecodingPathMixin:
7+
"""Decoding Path for list decoding."""
8+
9+
def __init__(self, **kwargs):
10+
super().__init__(**kwargs)
11+
12+
# Probability that current path contains correct decoding result
13+
self._path_metric = 0
14+
15+
def __eq__(self, other):
16+
return self._path_metric == other._path_metric
17+
18+
def __gt__(self, other):
19+
return self._path_metric > other._path_metric
20+
21+
def __ge__(self, other):
22+
return self > other or self == other
23+
24+
def __lt__(self, other):
25+
return not (self >= other)
26+
27+
def __le__(self, other):
28+
return not (self > other)
29+
30+
def __str__(self):
31+
return (
32+
f'LLR: {self.current_llr}; '
33+
f'Decision: {self._current_decision}; '
34+
f'Path metric: {self._path_metric}'
35+
)
36+
37+
@property
38+
def current_llr(self):
39+
return self.intermediate_llr[-1][0]
40+
41+
def __deepcopy__(self, memodict={}):
42+
new_path = self.__class__(n=self.n, mask=self.mask,
43+
is_systematic=self.is_systematic)
44+
45+
# Copy intermediate LLR values
46+
new_path.intermediate_llr = [
47+
np.array(llrs) for llrs in self.intermediate_llr
48+
]
49+
# Copy intermediate bit values
50+
new_path.intermediate_bits = [
51+
np.array(bits) for bits in self.intermediate_bits
52+
]
53+
# Copy current state
54+
new_path.current_state = np.array(self.current_state)
55+
# Copy previous state
56+
new_path.previous_state = np.array(self.previous_state)
57+
58+
# Copy path metric
59+
new_path._path_metric = self._path_metric
60+
61+
# Make opposite decisions for each path
62+
self._current_decision = 0
63+
new_path._current_decision = 1
64+
65+
return new_path
66+
67+
def update_path_metric(self):
68+
"""Update path metrics using LLR-based metric.
69+
70+
Source: https://arxiv.org/abs/1411.7282 Section III-B
71+
72+
"""
73+
if self.current_llr >= 0:
74+
self._path_metric -= (self.current_llr * self._current_decision)
75+
if self.current_llr < 0:
76+
self._path_metric += (self.current_llr * (1 - self._current_decision))
77+
78+
def split_path(self):
79+
"""Make a copy of SC path with another decision.
80+
81+
If LLR of the current position is out of bounds, there is no sense
82+
of splitting path because LLR >= 20 means 0 and LLR <= -20 means 1.
83+
84+
"""
85+
new_path = deepcopy(self)
86+
return [self, new_path]

python_polar_coding/polar_codes/base/encoder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22
from numba import njit
33

4-
from .crc import CRC
4+
from python_polar_coding.polar_codes.crc import CRC
55

66

77
class Encoder:

python_polar_coding/polar_codes/base/functions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def compute_encoding_step(level, n, source, result):
2020

2121

2222
@numba.njit
23-
def basic_llr_computation(a, b):
23+
def compute_alpha(a, b):
2424
"""Basic function to compute intermediate LLR values."""
2525
c = np.zeros(a.shape[0])
2626
for i in range(c.shape[0]):
@@ -35,7 +35,7 @@ def function_1(a, b, c):
3535
Source: doi:10.1007/s12243-018-0634-7, formula 1.
3636
3737
"""
38-
return basic_llr_computation(a, b + c)
38+
return compute_alpha(a, b + c)
3939

4040

4141
@numba.njit
@@ -45,7 +45,7 @@ def function_2(a, b, c):
4545
Source: doi:10.1007/s12243-018-0634-7, formula 2.
4646
4747
"""
48-
return basic_llr_computation(a, b) + c
48+
return compute_alpha(a, b) + c
4949

5050

5151
@numba.njit

python_polar_coding/polar_codes/base/crc.py renamed to python_polar_coding/polar_codes/crc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from PyCRC.CRC32 import CRC32
33
from PyCRC.CRCCCITT import CRCCCITT
44

5-
from . import utils
5+
from python_polar_coding.polar_codes import utils
66

77

88
class CRC:
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)