Skip to content

Commit

Permalink
Rework binary_code() and gray_code()
Browse files Browse the repository at this point in the history
Fixes #388
  • Loading branch information
mhostetter committed Jul 13, 2024
1 parent 5bb6fd4 commit e53d6f4
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/sdr/_modulation/_cpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ def __init__(
if isinstance(symbol_labels, str):
verify_literal(symbol_labels, ["bin", "gray"])
if symbol_labels == "bin":
self._symbol_labels = binary_code(self.bps)
self._symbol_labels = binary_code(self.order)
self._symbol_labels_str = "bin"
elif symbol_labels == "gray":
self._symbol_labels = gray_code(self.bps)
self._symbol_labels = gray_code(self.order)
self._symbol_labels_str = "gray"
else:
symbol_labels = verify_arraylike(symbol_labels, int=True, ndim=1, size=self.order)
Expand Down
8 changes: 4 additions & 4 deletions src/sdr/_modulation/_psk.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ def __init__(
if isinstance(symbol_labels, str):
verify_literal(symbol_labels, ["bin", "gray"])
if symbol_labels == "bin":
self._symbol_labels = binary_code(self.bps)
self._symbol_labels = binary_code(self.order)
self._symbol_labels_str = "bin"
elif symbol_labels == "gray":
self._symbol_labels = gray_code(self.bps)
self._symbol_labels = gray_code(self.order)
self._symbol_labels_str = "gray"
else:
symbol_labels = verify_arraylike(symbol_labels, int=True, ndim=1, size=self.order)
Expand Down Expand Up @@ -295,7 +295,7 @@ def ber(
if M == 2:
# Equation 4.3-13 from Proakis
Pbe = Q(np.sqrt(2 * ebn0_linear))
elif M == 4 and np.array_equal(self._symbol_labels, gray_code(k)):
elif M == 4 and np.array_equal(self._symbol_labels, gray_code(M)):
# Equation 4.3-13 from Proakis
Pbe = Q(np.sqrt(2 * ebn0_linear))
else:
Expand All @@ -313,7 +313,7 @@ def ber(
if M == 2:
# Equation 8.37 from Simon and Alouini
Pbe = 2 * Q(np.sqrt(2 * ebn0_linear)) - 2 * Q(np.sqrt(2 * ebn0_linear)) ** 2
elif M == 4 and np.array_equal(self._symbol_labels, gray_code(k)):
elif M == 4 and np.array_equal(self._symbol_labels, gray_code(M)):
# Equation 8.37 from Simon and Alouini
Pbe = 2 * Q(np.sqrt(2 * ebn0_linear)) - 2 * Q(np.sqrt(2 * ebn0_linear)) ** 2
else:
Expand Down
28 changes: 14 additions & 14 deletions src/sdr/_sequence/_symbol_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,63 +11,63 @@


@export
def binary_code(degree: int) -> npt.NDArray[np.int_]:
def binary_code(length: int) -> npt.NDArray[np.int_]:
"""
Generates a binary code of length $n = 2^m$.
Arguments:
degree: The degree $m$ of the binary code.
length: The length $n = 2^m$ of the binary code.
Returns:
A binary code of length $n = 2^m$.
Examples:
.. ipython:: python
sdr.binary_code(1)
sdr.binary_code(2)
sdr.binary_code(3)
sdr.binary_code(4)
sdr.binary_code(8)
sdr.binary_code(16)
Group:
sequences-symbol-mapping
"""
verify_scalar(degree, int=True, positive=True)
verify_scalar(length, int=True, positive=True, power_of_two=True)

return np.arange(2**degree)
return np.arange(length)


@export
def gray_code(degree: int) -> npt.NDArray[np.int_]:
def gray_code(length: int) -> npt.NDArray[np.int_]:
"""
Generates a Gray code of length $n = 2^m$.
Arguments:
degree: The degree $m$ of the Gray code.
length: The length $n = 2^m$ of the Gray code.
Returns:
A Gray code of length $n = 2^m$.
Examples:
.. ipython:: python
sdr.gray_code(1)
sdr.gray_code(2)
sdr.gray_code(3)
sdr.gray_code(4)
sdr.gray_code(8)
sdr.gray_code(16)
Group:
sequences-symbol-mapping
"""
verify_scalar(degree, int=True, positive=True)
verify_scalar(length, int=True, positive=True, power_of_two=True)

if degree == 1:
if length == 2:
return np.array([0, 1])

# Generate the Gray code with degree m - 1
code_1 = gray_code(degree - 1)
code_1 = gray_code(length // 2)

# Generate the Gray code for degree m by concatenating the Gray code for degree m - 1
# with itself reversed. Also, the most significant bit of the second half
# is set to 1.
return np.concatenate((code_1, code_1[::-1] + 2 ** (degree - 1)))
return np.concatenate((code_1, code_1[::-1] + length // 2))
8 changes: 4 additions & 4 deletions tests/modulation/test_binary_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@


def test_1():
code = sdr.binary_code(1)
code = sdr.binary_code(2)
code_truth = [0, 1]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)


def test_2():
code = sdr.binary_code(2)
code = sdr.binary_code(4)
code_truth = [0, 1, 2, 3]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)


def test_3():
code = sdr.binary_code(3)
code = sdr.binary_code(8)
code_truth = [0, 1, 2, 3, 4, 5, 6, 7]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)


def test_4():
code = sdr.binary_code(4)
code = sdr.binary_code(16)
code_truth = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)
8 changes: 4 additions & 4 deletions tests/modulation/test_gray_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@


def test_1():
code = sdr.gray_code(1)
code = sdr.gray_code(2)
code_truth = [0, 1]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)


def test_2():
code = sdr.gray_code(2)
code = sdr.gray_code(4)
code_truth = [0, 1, 3, 2]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)


def test_3():
code = sdr.gray_code(3)
code = sdr.gray_code(8)
code_truth = [0, 1, 3, 2, 6, 7, 5, 4]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)


def test_4():
code = sdr.gray_code(4)
code = sdr.gray_code(16)
code_truth = [0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8]
assert isinstance(code, np.ndarray)
assert np.array_equal(code, code_truth)

0 comments on commit e53d6f4

Please sign in to comment.