Skip to content

Decoder

Bases: object

Class representing basic SC (Successive Cancelation) decoder.

...

Attributes:

Name Type Description
Q NDArray[uint16]

Vector where indexes represent realiabilities and values represent polar sequence.

Methods:

Name Description
decode

Method for decoding code words.

Source code in src\decoder\sc_decoder.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
class Decoder(object):
    """
    Class representing basic SC (Successive Cancelation) decoder.

    ...
    Attributes
    ----------
    Q : NDArray[np.uint16]
        Vector where indexes represent realiabilities and values represent polar sequence.

    Methods
    -------
    decode()
        Method for decoding code words.
    """

    def __init__(self, Q: NDArray[np.uint16]):
        """
        Parameters
        ----------
        Q : NDArray[np.uint16]
            Vector where indexes represent realiabilities and values represent polar sequence.
        """
        self.Q = Q

    @staticmethod
    def createDecodingTree(root: DecodingTreeNode, depth: int) -> DecodingTreeNode:
        """"""
        if depth == 0:
            return root

        root.left_child = DecodingTreeNode()
        root.right_child = DecodingTreeNode()
        depth -= 1

        Decoder.createDecodingTree(root.left_child, depth)
        Decoder.createDecodingTree(root.right_child, depth)

        return root

    @staticmethod
    def combine(v1: NDArray[np.uint8], v2: NDArray[np.uint8]) -> NDArray[np.uint8]:
        """"""
        sum_mod2 = np.mod(v1 + v2, 2).astype(np.uint8)
        v2_uint8 = v2.astype(np.uint8)

        return np.concatenate([sum_mod2, v2_uint8])



    def decode(self, r: NDArray[np.float64], K: int) -> Tuple[NDArray[np.uint8], NDArray[np.uint8]]:
        """
        Function for decoding code word (polar code).

        Parameters
        ----------
        r : NDArray[np.float64]
            Encoded message (code word) after modulation (and channel influence).
        K : int
            Number of information bits.

        Returns
        -------
        NDArray[np.uint8]
            Decoded bit sequence.

        """

        N = r.size
        Q = self.Q[self.Q < N]
        frozen_bits_idxes = Q[:N-K]
        message_bits_idxes = Q[N-K:]

        def decodingTreeTraverse(root: DecodingTreeNode, L: NDArray[np.float64], bit_idx: int) -> Tuple[NDArray[np.uint8], NDArray[np.uint8], int]:
            """"""
            if root.left_child is None and root.right_child is None:
                if bit_idx in frozen_bits_idxes:
                    u = 0
                else:
                    u = 0 if L[0] >= 0 else 1

                return np.array([u]), np.array([u]), bit_idx + 1

            assert root.left_child and root.right_child

            left_L = root.f(L)
            u1, v1, bit_idx = decodingTreeTraverse(root.left_child, left_L, bit_idx)
            right_L = root.g(L, u1)
            u2, v2, bit_idx = decodingTreeTraverse(root.right_child, right_L, bit_idx)

            return Decoder.combine(u1, u2), np.concatenate([v1, v2]), bit_idx


        root = Decoder.createDecodingTree(root=DecodingTreeNode(), depth=int(log2(r.size)))
        recreated_r, decoded_seq, _ = decodingTreeTraverse(root, r, 0)

        return recreated_r, decoded_seq[message_bits_idxes]

__init__(Q)

Parameters:

Name Type Description Default
Q NDArray[uint16]

Vector where indexes represent realiabilities and values represent polar sequence.

required
Source code in src\decoder\sc_decoder.py
24
25
26
27
28
29
30
31
def __init__(self, Q: NDArray[np.uint16]):
    """
    Parameters
    ----------
    Q : NDArray[np.uint16]
        Vector where indexes represent realiabilities and values represent polar sequence.
    """
    self.Q = Q

combine(v1, v2) staticmethod

Source code in src\decoder\sc_decoder.py
48
49
50
51
52
53
54
@staticmethod
def combine(v1: NDArray[np.uint8], v2: NDArray[np.uint8]) -> NDArray[np.uint8]:
    """"""
    sum_mod2 = np.mod(v1 + v2, 2).astype(np.uint8)
    v2_uint8 = v2.astype(np.uint8)

    return np.concatenate([sum_mod2, v2_uint8])

createDecodingTree(root, depth) staticmethod

Source code in src\decoder\sc_decoder.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@staticmethod
def createDecodingTree(root: DecodingTreeNode, depth: int) -> DecodingTreeNode:
    """"""
    if depth == 0:
        return root

    root.left_child = DecodingTreeNode()
    root.right_child = DecodingTreeNode()
    depth -= 1

    Decoder.createDecodingTree(root.left_child, depth)
    Decoder.createDecodingTree(root.right_child, depth)

    return root

decode(r, K)

Function for decoding code word (polar code).

Parameters:

Name Type Description Default
r NDArray[float64]

Encoded message (code word) after modulation (and channel influence).

required
K int

Number of information bits.

required

Returns:

Type Description
NDArray[uint8]

Decoded bit sequence.

Source code in src\decoder\sc_decoder.py
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
def decode(self, r: NDArray[np.float64], K: int) -> Tuple[NDArray[np.uint8], NDArray[np.uint8]]:
    """
    Function for decoding code word (polar code).

    Parameters
    ----------
    r : NDArray[np.float64]
        Encoded message (code word) after modulation (and channel influence).
    K : int
        Number of information bits.

    Returns
    -------
    NDArray[np.uint8]
        Decoded bit sequence.

    """

    N = r.size
    Q = self.Q[self.Q < N]
    frozen_bits_idxes = Q[:N-K]
    message_bits_idxes = Q[N-K:]

    def decodingTreeTraverse(root: DecodingTreeNode, L: NDArray[np.float64], bit_idx: int) -> Tuple[NDArray[np.uint8], NDArray[np.uint8], int]:
        """"""
        if root.left_child is None and root.right_child is None:
            if bit_idx in frozen_bits_idxes:
                u = 0
            else:
                u = 0 if L[0] >= 0 else 1

            return np.array([u]), np.array([u]), bit_idx + 1

        assert root.left_child and root.right_child

        left_L = root.f(L)
        u1, v1, bit_idx = decodingTreeTraverse(root.left_child, left_L, bit_idx)
        right_L = root.g(L, u1)
        u2, v2, bit_idx = decodingTreeTraverse(root.right_child, right_L, bit_idx)

        return Decoder.combine(u1, u2), np.concatenate([v1, v2]), bit_idx


    root = Decoder.createDecodingTree(root=DecodingTreeNode(), depth=int(log2(r.size)))
    recreated_r, decoded_seq, _ = decodingTreeTraverse(root, r, 0)

    return recreated_r, decoded_seq[message_bits_idxes]