misc.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import numpy as np
  2. import math
  3. import matplotlib.pyplot as plt
  4. def display_alphabet(alphabet, values=None, a_vals=False, title="Alphabet constellation diagram"):
  5. rect = polar2rect(alphabet)
  6. if values is not None:
  7. rect2 = polar2rect(values)
  8. plt.plot(rect2[:, 0], rect2[:, 1], 'r.')
  9. plt.plot(rect[:, 0], rect[:, 1], 'b.', markersize=12)
  10. plt.title(title)
  11. N = math.ceil(math.log2(len(alphabet)))
  12. if a_vals:
  13. for i, value in enumerate(rect):
  14. plt.annotate(xy=value+[0.01, 0.01], s=format(i, f'0{N}b'))
  15. plt.xlabel('Real')
  16. plt.ylabel('Imaginary')
  17. plt.grid()
  18. plt.show()
  19. def polar2rect(array, amp_column=0, phase_column=1) -> np.ndarray:
  20. """
  21. Return copy of array with amp_column and phase_column as polar coordinates replaced by rectangular coordinates
  22. """
  23. if len(array) == 2 or len(array.shape) == 1:
  24. array = np.array([array])
  25. if array.shape[1] < 2:
  26. raise ValueError('Matrix has less than two columns')
  27. result = array.copy()
  28. result[:, amp_column] = np.cos(array[:, phase_column]) * array[:, amp_column]
  29. result[:, phase_column] = np.sin(array[:, phase_column]) * array[:, amp_column]
  30. return result
  31. def rect2polar(array, x_column=0, y_column=1) -> np.ndarray:
  32. """
  33. Return copy of array with x_column and y_column as rectangular coordinates replaced by polar coordinates
  34. """
  35. if len(array) == 2 or len(array.shape) == 1:
  36. array = np.array([array])
  37. if array.shape[1] < 2:
  38. raise ValueError('Matrix has less than two columns')
  39. x_arr = array[:, x_column]
  40. y_arr = array[:, y_column]
  41. result = array.copy()
  42. result[:, x_column] = np.sqrt(x_arr**2 + y_arr**2)
  43. result[x_arr != 0, y_column] = np.arctan(y_arr[x_arr != 0, ] / x_arr[x_arr != 0, ])
  44. result[np.bitwise_and(x_arr == 0, y_arr < 0), y_column] = -np.pi / 2
  45. result[np.bitwise_and(x_arr == 0, y_arr == 0), y_column] = 0
  46. result[np.bitwise_and(x_arr == 0, y_arr > 0), y_column] = np.pi / 2
  47. result[np.bitwise_and(x_arr < 0, y_arr < 0), y_column] -= np.pi
  48. result[np.bitwise_and(x_arr < 0, y_arr >= 0), y_column] += np.pi
  49. return result
  50. def generate_random_bit_array(size):
  51. z, o = np.zeros(int(size // 2), dtype=bool), np.ones(int(size // 2), dtype=bool)
  52. if size % 2 == 1:
  53. p = (z, o, [np.random.choice([True, False])])
  54. else:
  55. p = (z, o)
  56. arr = np.concatenate(p)
  57. np.random.shuffle(arr)
  58. return arr