forked from xukmin/viterbi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathviterbi.py
65 lines (56 loc) · 2.43 KB
/
viterbi.py
1
2
3
4
5
6
7
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
from viterbicodec import ViterbiCodec, reverse_bits
__all__ = ["Viterbi"]
def list2str(bits):
return "".join(map(lambda x: "1" if x > 0 else "0", bits))
def str2list(bits):
return list(map(lambda x: 1 if x == "1" else 0, bits))
class Viterbi(ViterbiCodec):
def __init__(self, constraint, polynomials, puncpat=[]):
if constraint <= 0:
raise Exception("Constraint should be greater than 0.")
for i in range(len(polynomials)):
if polynomials[i] <= 0:
raise Exception("Polynomial should be greater than 0.")
if polynomials[i] >= (1 << constraint):
raise Exception(f"Polynomial should be less than {1 << constraint}")
polynomials[i] = reverse_bits(constraint, polynomials[i])
self.constraint = constraint
self.polynomials = polynomials
if len(puncpat) == 0:
ViterbiCodec.__init__(self, constraint, polynomials, "")
else:
ViterbiCodec.__init__(self, constraint, polynomials, list2str(puncpat))
self.puncpat = puncpat if len(puncpat) > 0 else [1]
self.puncpat_ones_len = self.puncpat.count(1)
self.is_punctured = len(puncpat) > 0
def encode(self, bits):
if (
self.is_punctured
and len(bits) * len(self.polynomials) % len(self.puncpat) != 0
):
raise Exception(
"The length of bits divided by the base code rate must be an integer multiple of the length of the puncture pattern."
)
bits = list2str(bits)
output = ViterbiCodec.encode(self, bits)
return str2list(output)
def decode(self, bits):
if self.is_punctured and len(bits) % self.puncpat_ones_len != 0:
raise Exception(
"The length of bits must be an integer multiple of the number of ones in the puncture pattern."
)
if (
len(bits)
/ self.puncpat_ones_len
* len(self.puncpat)
% len(self.polynomials)
!= 0
):
raise Exception(
"The length of bits divided by the number of ones in the puncture pattern "
+ "times the length of the puncture pattern must be an integer multiple of the number "
+ "of bits in an input symbol."
)
bits = list2str(bits)
output = ViterbiCodec.decode(self, bits)
return str2list(output)