Skip to content

Commit 795dbb7

Browse files
committed
Add Gray code support for Modems
Close #100 and #60
1 parent 46512b9 commit 795dbb7

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

commpy/modulation.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@
2121
2222
"""
2323
from bisect import insort
24-
from itertools import product
2524

2625
import matplotlib.pyplot as plt
27-
from numpy import arange, array, zeros, pi, cos, sin, sqrt, log2, argmin, \
26+
from numpy import arange, array, zeros, pi, sqrt, log2, argmin, \
2827
hstack, repeat, tile, dot, shape, concatenate, exp, \
29-
log, vectorize, empty, eye, kron, inf, full, abs, newaxis, minimum, clip
28+
log, vectorize, empty, eye, kron, inf, full, abs, newaxis, minimum, clip, fromiter
3029
from numpy.fft import fft, ifft
3130
from numpy.linalg import qr, norm
31+
from sympy.combinatorics.graycode import GrayCode
3232

3333
from commpy.utilities import bitarray2dec, dec2bitarray, signal_power
3434

@@ -65,10 +65,16 @@ class Modem:
6565
If the constellation is changed to an array-like with length that is not a power of 2.
6666
"""
6767

68-
def __init__(self, constellation):
68+
def __init__(self, constellation, reorder_as_gray=True):
6969
""" Creates a custom Modem object. """
7070

71-
self.constellation = constellation
71+
if reorder_as_gray:
72+
m = log2(len(constellation))
73+
gray_code_sequence = GrayCode(m).generate_gray()
74+
gray_code_sequence_array = fromiter((int(g, 2) for g in gray_code_sequence), int, len(constellation))
75+
self.constellation = constellation[gray_code_sequence_array.argsort()]
76+
else:
77+
self.constellation = constellation
7278

7379
def modulate(self, input_bits):
7480
""" Modulate (map) an array of bits to constellation symbols.
@@ -197,10 +203,7 @@ class PSKModem(Modem):
197203
def __init__(self, m):
198204
""" Creates a Phase Shift Keying (PSK) Modem object. """
199205

200-
def _constellation_symbol(i):
201-
return cos(2 * pi * (i - 1) / m) + sin(2 * pi * (i - 1) / m) * (0 + 1j)
202-
203-
self.constellation = list(map(_constellation_symbol, arange(m)))
206+
super().__init__(exp(1j * arange(0, 2 * pi, 2 * pi / m)))
204207

205208

206209
class QAMModem(Modem):
@@ -241,12 +244,10 @@ def __init__(self, m):
241244
242245
"""
243246

244-
def _constellation_symbol(i):
245-
return (2 * i[0] - 1) + (2 * i[1] - 1) * (1j)
246-
247-
mapping_array = arange(1, sqrt(m) + 1) - (sqrt(m) / 2)
248-
self.constellation = list(map(_constellation_symbol,
249-
list(product(mapping_array, repeat=2))))
247+
num_symb_pam = int(sqrt(m))
248+
pam = arange(-num_symb_pam + 1, num_symb_pam, 2)
249+
constellation = tile(hstack((pam, pam[::-1])), num_symb_pam // 2) * 1j + pam.repeat(num_symb_pam)
250+
super().__init__(constellation)
250251

251252

252253
def ofdm_tx(x, nfft, nsc, cp_length):

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ numpy>=1.9.2
22
scipy>=0.15.0
33
matplotlib>=1.4.3
44
nose>=1.3.4
5+
sympy>=1.7.1

0 commit comments

Comments
 (0)