Advertisement
Falexom

Untitled

Jun 1st, 2023 (edited)
850
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.18 KB | None | 0 0
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from sympy import Matrix, Poly, div, symbols
  4. from functools import reduce
  5.  
  6.  
  7. def cyclotomic_cosets(order):
  8.     cosets = []
  9.     for i in range(order):
  10.         coset = set()
  11.         for j in range(order):
  12.             element = (2**j * i) % order
  13.             coset.add(element)
  14.         if coset not in cosets:
  15.             cosets.append(coset)
  16.     return cosets[1:]
  17.  
  18.  
  19. def minimal_polynomials(cosets):
  20.     x = symbols("x")
  21.     min_polys = []
  22.  
  23.     for coset in cosets:
  24.         polys = [Poly(x - a, domain="GF(2)") for a in coset]
  25.         min_poly = reduce(lambda poly1, poly2: poly1 * poly2, polys)
  26.         min_poly += 1
  27.         min_polys.append(min_poly)
  28.  
  29.     return min_polys
  30.  
  31.  
  32. def generate_poly(cosets, min_polys, error_correction):
  33.     order = max(max(coset) for coset in cosets) + 1
  34.     selected_polys = [
  35.         min_polys[i] for i in range(1, 2 * error_correction + 1) if i < order
  36.     ]
  37.     generator_poly = reduce(lambda a, b: a * b, selected_polys)
  38.     generator_poly = Poly(generator_poly, domain="GF(2)")
  39.     return generator_poly
  40.  
  41.  
  42. def bch_params(generator_poly, order):
  43.     n_k = generator_poly.degree()
  44.     k = order - n_k
  45.     t = sum(generator_poly.as_expr().as_coefficients_dict().values()) // 2
  46.     return k, t
  47.  
  48.  
  49. def encode_message(vector, order, info_bits, generator_poly):
  50.     x = symbols("x")
  51.     info_poly = Poly(vector, x, domain="GF(2)")
  52.     info_poly = info_poly * x ** (order - info_bits)
  53.     quotient, remainder = div(info_poly, generator_poly)
  54.     encoded_message = info_poly + remainder
  55.     encoded_message = np.array(encoded_message.all_coeffs()[::-1]) % 2
  56.     return encoded_message
  57.  
  58.  
  59. def decode_message(encoded_message, order, info_bits, generator_poly):
  60.     x = symbols("x")
  61.     encoded_message = Poly(encoded_message, x, domain="GF(2)")
  62.     quotient, remainder = div(encoded_message, generator_poly)
  63.     decoded_message = quotient * x ** (order - info_bits)
  64.     decoded_message = np.array(decoded_message.all_coeffs()[::-1]) % 2
  65.     return decoded_message
  66.  
  67.  
  68. def noisy_channel(bits, snr):
  69.     noise = np.random.binomial(n=1, p=1 - 1 / (1 + snr), size=len(bits))
  70.     return bits ^ noise
  71.  
  72.  
  73. def simulate_bch(order, info_bits, snr, num_messages):
  74.     errors = 0
  75.     total_bits = 0
  76.     for _ in range(num_messages):
  77.         message = np.random.randint(2, size=info_bits)
  78.         encoded_message = encode_message(message, order, info_bits, generator_poly)
  79.         received_message = noisy_channel(encoded_message, snr)
  80.         decoded_message = decode_message(
  81.             received_message, order, info_bits, generator_poly
  82.         )
  83.         errors += np.sum(message != decoded_message)
  84.         total_bits += len(message)
  85.     return errors / total_bits
  86.  
  87.  
  88. order = 63
  89. info_bits = 36
  90. error_locations = [18, 5]
  91.  
  92. cosets = cyclotomic_cosets(order)
  93.  
  94. min_polys = minimal_polynomials(cosets)
  95.  
  96. generator_poly = generate_poly(cosets, min_polys, 3)
  97.  
  98. info_bits, error_correction = bch_params(generator_poly, order)
  99.  
  100. parity_check_matrix = Matrix.zeros(order - info_bits, order)
  101. n_k = order - info_bits
  102. coeffs = generator_poly.all_coeffs()[::-1]
  103.  
  104. for i in range(n_k):
  105.     for j in range(order):
  106.         parity_check_matrix[i, j] = coeffs[(i + j) % n_k]
  107.  
  108. message_vector = [0] * 33 + [0, 0, 1, 0, 1, 1, 1]
  109. encoded_message = encode_message(message_vector, order, info_bits, generator_poly)
  110. encoded_message[error_locations[0]] ^= 1
  111. encoded_message[error_locations[1]] ^= 1
  112. decoded_message = decode_message(encoded_message, order, info_bits, generator_poly)
  113. snrs = np.linspace(0, 10, 11)
  114. num_messages = 1000
  115. error_probs_31_21 = [simulate_bch(31, 21, snr, num_messages) for snr in snrs]
  116. error_probs_15_7 = [simulate_bch(15, 7, snr, num_messages) for snr in snrs]
  117. plt.figure(figsize=(8, 6))
  118. plt.semilogy(snrs, error_probs_31_21, label="BCH (31, 21)", color='red', marker='o')
  119. plt.semilogy(snrs, error_probs_15_7, label="BCH (15, 7)", color='blue', marker='o')
  120. plt.xlabel("SNR (dB)")
  121. plt.ylabel("Вероятность ошибки на бит")
  122. plt.title("Вероятность ошибки на бит относительно SNR")
  123. plt.legend()
  124. plt.grid(True)
  125. plt.gca().set_facecolor('dimgray')
  126. plt.show()
  127.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement