misc.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import numpy as np
  2. import math
  3. import matplotlib.pyplot as plt
  4. import pickle
  5. def display_alphabet(alphabet, values=None, a_vals=False, title="Alphabet constellation diagram"):
  6. rect = polar2rect(alphabet)
  7. if values is not None:
  8. rect2 = polar2rect(values)
  9. plt.plot(rect2[:, 0], rect2[:, 1], 'r.')
  10. plt.plot(rect[:, 0], rect[:, 1], 'b.', markersize=12)
  11. plt.title(title)
  12. N = math.ceil(math.log2(len(alphabet)))
  13. if a_vals:
  14. for i, value in enumerate(rect):
  15. plt.annotate(xy=value+[0.01, 0.01], text=format(i, f'0{N}b'))
  16. plt.xlabel('Real')
  17. plt.ylabel('Imaginary')
  18. plt.grid()
  19. plt.show()
  20. def bit_matrix2one_hot(matrix: np.ndarray) -> np.ndarray:
  21. """
  22. Returns a copy of bit encoded matrix to one hot matrix. A row examples:
  23. [1010] (decimal 10) => [0000 0100 0000 0000]
  24. [0011] (decimal 3) => [0000 0000 0000 1000]
  25. each number represents true/false value in column
  26. """
  27. N = matrix.shape[1]
  28. encoder = 2**np.arange(N)
  29. values = np.dot(matrix, encoder)
  30. result = np.zeros((matrix.shape[0], 2**N), dtype=bool)
  31. result[np.arange(matrix.shape[0]), values] = True
  32. return result
  33. def one_hot2bit_matrix(matrix: np.ndarray) -> np.ndarray:
  34. """
  35. Returns a copy of one hot matrix to bit encoded matrix. A row examples:
  36. [0000 0100 0000 0000] => [1010] (decimal 10)
  37. [0000 0000 0000 1000] => [0011] (decimal 3)
  38. each number represents true/false value in column
  39. """
  40. N = math.ceil(math.log2(matrix.shape[1]))
  41. values = np.dot(matrix, np.arange(2**N))
  42. return int2bit_array(values, N)
  43. def int2bit_array(int_arr: np.ndarray, N: int) -> np.ndarray:
  44. x0 = np.array([int_arr], dtype=np.uint8)
  45. x1 = np.unpackbits(x0.T, bitorder='little', axis=1)
  46. result = x1[:, :N].astype(bool) # , indices
  47. return result
  48. def polar2rect(array, amp_column=0, phase_column=1) -> np.ndarray:
  49. """
  50. Return copy of array with amp_column and phase_column as polar coordinates replaced by rectangular coordinates
  51. """
  52. if len(array) == 2 or len(array.shape) == 1:
  53. array = np.array([array])
  54. if array.shape[1] < 2:
  55. raise ValueError('Matrix has less than two columns')
  56. result = array.copy()
  57. result[:, amp_column] = np.cos(array[:, phase_column]) * array[:, amp_column]
  58. result[:, phase_column] = np.sin(array[:, phase_column]) * array[:, amp_column]
  59. return result
  60. def rect2polar(array, x_column=0, y_column=1) -> np.ndarray:
  61. """
  62. Return copy of array with x_column and y_column as rectangular coordinates replaced by polar coordinates
  63. """
  64. if len(array) == 2 or len(array.shape) == 1:
  65. array = np.array([array])
  66. if array.shape[1] < 2:
  67. raise ValueError('Matrix has less than two columns')
  68. x_arr = array[:, x_column]
  69. y_arr = array[:, y_column]
  70. result = array.copy()
  71. result[:, x_column] = np.sqrt(x_arr**2 + y_arr**2)
  72. result[x_arr != 0, y_column] = np.arctan(y_arr[x_arr != 0, ] / x_arr[x_arr != 0, ])
  73. result[np.bitwise_and(x_arr == 0, y_arr < 0), y_column] = -np.pi / 2
  74. result[np.bitwise_and(x_arr == 0, y_arr == 0), y_column] = 0
  75. result[np.bitwise_and(x_arr == 0, y_arr > 0), y_column] = np.pi / 2
  76. result[np.bitwise_and(x_arr < 0, y_arr < 0), y_column] -= np.pi
  77. result[np.bitwise_and(x_arr < 0, y_arr >= 0), y_column] += np.pi
  78. return result
  79. def generate_random_bit_array(size):
  80. z, o = np.zeros(int(size // 2), dtype=bool), np.ones(int(size // 2), dtype=bool)
  81. if size % 2 == 1:
  82. p = (z, o, [np.random.choice([True, False])])
  83. else:
  84. p = (z, o)
  85. arr = np.concatenate(p)
  86. np.random.shuffle(arr)
  87. return arr
  88. def picke_save(obj, fname):
  89. with open(fname, 'wb') as f:
  90. pickle.dump(obj, f)
  91. def picke_load(fname):
  92. with open(fname, 'rb') as f:
  93. return pickle.load(f)