BER
import numpy as np
import matplotlib.pyplot as plt
import csv
def calculate_ber(received_symbols, transmitted_symbols):
"""
Calculate the bit error rate (BER) for QAM signals.
Args:
received_symbols (numpy array): Array of received QAM symbols.
transmitted_symbols (numpy array): Array of transmitted QAM symbols.
Returns:
ber (float): Bit error rate (BER).
"""
# Calculate the number of symbols and bits
num_symbols = len(received_symbols)
num_bits = num_symbols * np.log2(len(transmitted_symbols))
# Convert symbols to bits
received_bits = np.unpackbits(received_symbols.view(np.uint8))[:int(num_bits)]
transmitted_bits = np.unpackbits(transmitted_symbols.view(np.uint8))[:int(num_bits)]
# Calculate the number of bit errors
num_errors = np.sum(received_bits != transmitted_bits)
# Calculate the bit error rate (BER)
ber = num_errors / num_bits
return ber
def qam_bit_error_rate(snr_db, num_symbols, bits_per_symbol):
"""
Calculate the bit error rate (BER) for QAM signals under given SNR.
Args:
snr_db (numpy array): Array of SNR values in dB.
num_symbols (int): Number of QAM symbols to generate.
bits_per_symbol (int): Number of bits per QAM symbol.
Returns:
ber (numpy array): Array of bit error rates (BER) corresponding to each SNR value.
"""
ber = []
for snr in snr_db:
# Generate random QAM symbols
transmitted_symbols = np.random.randint(0, 2**bits_per_symbol, num_symbols)
# Add Gaussian noise to the transmitted symbols
snr_linear = 10**(snr / 10.0)
noise_std = np.sqrt(1 / (2 * snr_linear))
noise = noise_std * np.random.randn(num_symbols)
received_symbols = transmitted_symbols + noise
# Calculate the BER
ber.append(calculate_ber(received_symbols, transmitted_symbols))
return np.array(ber)
# SNR range for BER plot
snr_db = np.arange(0, 20, 2) # Signal-to-Noise Ratio (SNR) range in dB
num_symbols = 100000 # Number of QAM symbols
bits_per_symbol_4qam = 2 # Number of bits per 16-QAM symbol
ber_4qam = qam_bit_error_rate(snr_db, num_symbols, bits_per_symbol_4qam)
bits_per_symbol_8qam = 3 # Number of bits per 64-QAM symbol
ber_8qam = qam_bit_error_rate(snr_db, num_symbols, bits_per_symbol_8qam)
bits_per_symbol_16qam = 4 # Number of bits per 64-QAM symbol
ber_16qam = qam_bit_error_rate(snr_db, num_symbols, bits_per_symbol_16qam)
# Plot the BER vs. SNR
plt.plot(snr_db, ber_4qam, marker='o', label='4-QAM')
plt.plot(snr_db, ber_8qam, marker='o', label='8-QAM')
plt.plot(snr_db, ber_16qam, marker='o', label='16-QAM')
plt.xlabel('SNR (dB)')
plt.ylabel('Bit Error Rate (BER)')
plt.title('4,8,16-bit BER of QAM')
plt.legend()
plt.grid(True)
plt.savefig('BER VS SNR.png', dpi=800)
plt.show()
with open('BER.csv', 'w', encoding='UTF8') as f:
writer = csv.writer(f)
# write the header
writer.writerow(snr_db)
# write the data
writer.writerow(ber_4qam)
writer.writerow(ber_8qam)
writer.writerow(ber_16qam
papr
import numpy as np
import matplotlib.pyplot as plt
import csv
def calculate_papr(modulation_order):
# Generate random QAM symbols
num_symbols = 10**4
qam_symbols = np.random.randint(0, modulation_order, num_symbols)
# Convert QAM symbols to complex symbols
complex_symbols = qam_modulation(qam_symbols, modulation_order)
# Calculate the PAPR
papr = np.max(np.abs(complex_symbols) * 2) / np.mean(np.abs(complex_symbols) * 2)
return papr
def qam_modulation(qam_symbols, modulation_order):
# Mapping table for QAM modulation
qam_mapping = {
4: [-1 - 1j, -1 + 1j, 1 - 1j, 1 + 1j],
8: [-3 + 3j, -3 + 1j, -1 + 3j, -1 + 1j, -3 - 3j, -3 - 1j, -1 - 3j, -1 - 1j],
16: [-3 - 3j, -3 - 1j, -3 + 3j, -3 + 1j, -1 - 3j, -1 - 1j, -1 + 3j, -1 + 1j,
3 - 3j, 3 - 1j, 3 + 3j, 3 + 1j, 1 - 3j, 1 - 1j, 1 + 3j, 1 + 1j]
return np.array([qam_mapping[modulation_order][symbol] for symbol in qam_symbols])
# Modulation order
modulation_orders = [4, 8, 16]
for modulation_order in modulation_orders:
# Calculate PAPR for each symbol
papr_values = []
for _ in range(10):
papr = calculate_papr(modulation_order)
papr_values.append(papr)
# Plot the PAPR waveform
plt.plot(np.arange(len(papr_values)), papr_values, marker='o')
plt.xlabel('Symbol Index')
plt.ylabel('PAPR')
plt.title('PAPR Waveform for {}-QAM'.format(modulation_order))
plt.grid(True)
plt.savefig('PAPR_{} bit.png'.format(modulation_order), dpi=800)
plt.show()
# Save PAPR values to CSV
with open('PAPR.csv', 'a', encoding='UTF8') as f:
writer = csv.writer(f)
writer.writerow(papr_values
snr
import numpy as np
import matplotlib.pyplot as plt
import csv
def calculate_snr(snr_dB, modulation_order):
snr = 10 ** (snr_dB / 10) # Convert SNR from dB to linear scale
noise_var = 1 / (2 * snr) # Noise variance
# Generate random QAM symbols
num_symbols = 10**4
qam_symbols = np.random.randint(0, modulation_order, num_symbols)
# Convert QAM symbols to complex symbols
complex_symbols = qam_modulation(qam_symbols, modulation_order)
# Add AWGN noise to the complex symbols
noisy_symbols = complex_symbols + np.sqrt(noise_var / 2) * (np.random.randn(num_symbols) + 1j
* np.random.randn(num_symbols))
# Calculate the received power
received_power = np.mean(np.abs(noisy_symbols) ** 2)
return received_power / noise_var
def qam_modulation(qam_symbols, modulation_order):
# Mapping table for QAM modulation
qam_mapping = {
4: [-1 - 1j, -1 + 1j, 1 - 1j, 1 + 1j],
8: [-3 +3j, -3+1j, -1+3j, -1+1j, -3+-3j, -3+-1j, -1+-3j, -1+-1j],
16: [-3 - 3j, -3 - 1j, -3 + 3j, -3 + 1j, -1 - 3j, -1 - 1j, -1 + 3j, -1 + 1j,
3 - 3j, 3 - 1j, 3 + 3j, 3 + 1j, 1 - 3j, 1 - 1j, 1 + 3j, 1 + 1j],
32: [-7+7j,-7+5j,-5+7,-5+5j,-7+1j,-7+3j,-5+1j,-5+3j,-3+7j,-3+5j,-1+7j,-1+5j,-3+1j,-3+3j,-1+1j,-1+3j,-
7+-7j,-7+-5j,-5+-7j,-5+-5j,-7+-1j,-7+-3j,-5+-1j,-5+-3j,-3+-7j,-3+-5j,-1+-7j,-1+-5j,-3+-1j,-3+-3j,-1+-1j,-1+-
3j],
64: [-7 +7j, -5 +7j, -3 +7j, -1 +7j, -7 + 5j, -5+ 5j, -3+ 5j, -1+ 5j, -7+3j, -5 +3j, -3+3j, -1+3j, -7+1j, -
5+1j, -3+1j, -1+1j, -7+-7j, -5+-7j, -3+-7j, -1+-7j, -7+-5j, -5+-5j, -3+-5j, -1+-5j, -7+-3j, -5+-3j, -3+-3j, -1+-
3j, -7+-1j, -5+-1j, -3+-1j, -1+-1j, 7+7j, 5+7j, 3+7j, 1+7j, 7+5j, 5+5j, 3+5j, 1+5j, 7+3j, 5+3j, 3+3j, 1+3j,
7+1j, 5+1j, 3+1j, 1+1j, 7+-7j, 5+-7j, 3+-7j, 1+-7j, 7+-5j, 5+-5j, 3+-5j, 1+-5j, 7+-3j, 5+-3j, 3+-3j, 1+-3j, 7+-
1j, 5+-1j, 3+-1j, 1+-1j]
}
return np.array([qam_mapping[modulation_order][symbol] for symbol in qam_symbols])
# SNR range in dB
snr_dB_range = np.arange(0, 20, 1)
# Modulation orders
modulation_orders = [4, 8, 16]
# Calculate SNR for each SNR value
snr_values = {}
for modulation_order in modulation_orders:
snr_values[modulation_order] = []
for snr_dB in snr_dB_range:
snr = calculate_snr(snr_dB, modulation_order)
snr_values[modulation_order].append(snr)
# Plot the SNR waveforms
for modulation_order in modulation_orders:
plt.plot(snr_dB_range, snr_values[modulation_order], marker='o')
plt.xlabel('SNR (dB)')
plt.ylabel('SNR (linear scale)')
plt.title('SNR Waveform for {}-QAM'.format(modulation_order))
plt.grid(True)
plt.savefig('SNR_{}bit.png'.format(modulation_order), dpi=800)
plt.show()
# Save SNR values to CSV file
with open('SNR.csv', 'w', encoding='UTF8') as f:
writer = csv.writer(f)
writer.writerow(snr_dB_range)
for modulation_order in modulation_orders:
writer.writerow(snr_values[modulation_order])