Skip to content

Commit 86fea97

Browse files
authored
Merge pull request #18 from YairMZ/bp_decoder
Refactored WiFi spec out of encoder package. Added a WiFi decoder based on spec.
2 parents ac0ad59 + 74e9a21 commit 86fea97

File tree

9 files changed

+61
-28
lines changed

9 files changed

+61
-28
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ simulations.
3737
import numpy as np
3838
from bitstring import BitArray, Bits
3939
from ldpc.decoder import LogSpaDecoder, bsc_llr
40-
from ldpc.encoder import EncoderWiFi, WiFiSpecCode
40+
from ldpc.encoder import EncoderWiFi
41+
from ldpc.wifi_spec_codes import WiFiSpecCode
4142
from ldpc.utils import QCFile
4243

4344
# create information bearing bits

examples/ieee802_11_example.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import numpy as np
22
from bitstring import BitArray, Bits
3-
from ldpc.decoder import LogSpaDecoder, bsc_llr
4-
from ldpc.encoder import EncoderWiFi, WiFiSpecCode
3+
from ldpc.decoder import DecoderWiFi, bsc_llr
4+
from ldpc.encoder import EncoderWiFi
5+
from ldpc.wifi_spec_codes import WiFiSpecCode
56
from ldpc.utils import QCFile
67

78
# create information bearing bits
@@ -19,7 +20,7 @@
1920
# create a decoder which assumes a probability of p=0.05 for bit flips by the channel
2021
# allow up to 20 iterations for the bp decoder.
2122
p = 0.05
22-
decoder = LogSpaDecoder(bsc_llr(p=p), h=h, max_iter=20, info_idx=np.array([True]*324 + [False]*324))
23+
decoder = DecoderWiFi(bsc_llr(p=p), spec=WiFiSpecCode.N648_R12, max_iter=20, info_idx=np.array([True]*324 + [False]*324))
2324

2425
# create a corrupted version of encoded codeword with error rate p
2526
corrupted = BitArray(encoded)

ldpc/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from ldpc.base_code import CodeStructure
2-
__all__: list[str] = ["CodeStructure"]
2+
from ldpc.wifi_spec_codes import WiFiSpecCode
3+
__all__: list[str] = ["CodeStructure", "WiFiSpecCode"]

ldpc/decoder/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from ldpc.decoder.log_spa_decoder import LogSpaDecoder, InfoBitsNotSpecified
22
from ldpc.decoder.channel_models import bsc_llr
3+
from ldpc.decoder.ieee802_11_decoder import DecoderWiFi
34

4-
__all__: list[str] = ["LogSpaDecoder", "bsc_llr", "InfoBitsNotSpecified"]
5+
__all__: list[str] = ["LogSpaDecoder", "bsc_llr", "InfoBitsNotSpecified", "DecoderWiFi"]

ldpc/decoder/ieee802_11_decoder.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from ldpc.decoder.log_spa_decoder import *
2+
from numpy.typing import NDArray
3+
import numpy as np
4+
from ldpc.decoder.channel_models import ChannelModel
5+
from typing import Optional
6+
from ldpc.wifi_spec_codes import WiFiSpecCode
7+
import os
8+
from ldpc.utils.qc_format import QCFile
9+
10+
11+
class DecoderWiFi(LogSpaDecoder):
12+
"""Decode messages according to the codes in the IEEE802.11n standard using Log SPA decoder"""
13+
_spec_base_path: str = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'code_specs', 'ieee802.11')
14+
15+
def __init__(self, channel_model: ChannelModel, spec: WiFiSpecCode, max_iter: int,
16+
info_idx: Optional[NDArray[np.bool_]] = None):
17+
"""
18+
19+
:param channel_model: a callable which receives a channel input, and returns the channel llr
20+
:param spec: specify which code from the spec we use
21+
:param max_iter: The maximal number of iterations for belief propagation algorithm
22+
:param info_idx: a boolean array representing the indices of information bits in the code
23+
"""
24+
self.spec = spec
25+
qc_file = QCFile.from_file(os.path.join(self._spec_base_path, spec.name + ".qc"))
26+
h = qc_file.to_array()
27+
super().__init__(channel_model, h, max_iter, info_idx)

ldpc/encoder/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from ldpc.encoder.base_encoder import Encoder
22
from ldpc.encoder.generator_based_encoder import EncoderG
3-
from ldpc.encoder.ieee802_11_encoder import WiFiSpecCode, EncoderWiFi
4-
__all__: list[str] = ["Encoder", "EncoderG", "WiFiSpecCode", "EncoderWiFi"]
3+
from ldpc.encoder.ieee802_11_encoder import EncoderWiFi
4+
__all__: list[str] = ["Encoder", "EncoderG", "EncoderWiFi"]

ldpc/encoder/ieee802_11_encoder.py

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,23 @@
1-
from enum import Enum, auto
21
from ldpc.encoder.base_encoder import Encoder
32
import numpy as np
43
from bitstring import Bits
54
from ldpc.utils.custom_exceptions import IncorrectLength
65
from ldpc.utils.qc_format import QCFile
76
import os
87
from numpy.typing import NDArray
9-
10-
11-
class WiFiSpecCode(Enum):
12-
"""Enumerate models"""
13-
N648_R12 = auto()
14-
N648_R23 = auto()
15-
N648_R34 = auto()
16-
N648_R56 = auto()
17-
N1296_R12 = auto()
18-
N1296_R23 = auto()
19-
N1296_R34 = auto()
20-
N1296_R56 = auto()
21-
N1944_R12 = auto()
22-
N1944_R23 = auto()
23-
N1944_R34 = auto()
24-
N1944_R56 = auto()
8+
from ldpc.wifi_spec_codes import WiFiSpecCode
259

2610

2711
class EncoderWiFi(Encoder):
2812
"""Encode messages according to the codes in the IEEE802.11n standard"""
29-
spec_base_path: str = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'code_specs', 'ieee802.11')
13+
_spec_base_path: str = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'code_specs', 'ieee802.11')
3014

3115
def __init__(self, spec: WiFiSpecCode) -> None:
3216
"""
3317
:param spec: specify which code from the spec we use
3418
"""
3519
self.spec = spec
36-
qc_file = QCFile.from_file(os.path.join(self.spec_base_path, spec.name + ".qc"))
20+
qc_file = QCFile.from_file(os.path.join(self._spec_base_path, spec.name + ".qc"))
3721
self.h = qc_file.to_array()
3822
self.m, n = self.h.shape
3923
k = n - self.m

ldpc/wifi_spec_codes.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from enum import Enum, auto
2+
3+
4+
class WiFiSpecCode(Enum):
5+
"""Enumerate codes"""
6+
N648_R12 = auto()
7+
N648_R23 = auto()
8+
N648_R34 = auto()
9+
N648_R56 = auto()
10+
N1296_R12 = auto()
11+
N1296_R23 = auto()
12+
N1296_R34 = auto()
13+
N1296_R56 = auto()
14+
N1944_R12 = auto()
15+
N1944_R23 = auto()
16+
N1944_R34 = auto()
17+
N1944_R56 = auto()

tests/test_ieee802_11.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22
from bitstring import Bits, BitArray
3-
from ldpc.encoder import WiFiSpecCode, EncoderWiFi
3+
from ldpc.encoder import EncoderWiFi
4+
from ldpc.wifi_spec_codes import WiFiSpecCode
45
import pytest
56
from ldpc.utils import IncorrectLength, QCFile
67
from ldpc.decoder import LogSpaDecoder, bsc_llr, InfoBitsNotSpecified

0 commit comments

Comments
 (0)