-
Notifications
You must be signed in to change notification settings - Fork 2
/
conv_codes.py
116 lines (78 loc) · 3.32 KB
/
conv_codes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import os
import numpy as np
from PIL import Image
from matplotlib import pyplot as plt
import komm
import FEC
if __name__ == '__main__':
"""
Main function
"""
# arguments
import argparse
# Create argument parser object
parser = argparse.ArgumentParser()
parser.add_argument('-d', action='store')
# Create a namespace
args = parser.parse_args()
script_dir = os.path.abspath(os.path.dirname(__file__))
image_path = os.path.join(script_dir, 'data/DC4_150x100.pgm')
# input image
tx_im = Image.open(image_path)
# number of pixels
Npixels = tx_im.size[1] * tx_im.size[0]
# # plot input image
# plt.figure(1)
# plt.title('Input Image')
# plt.imshow(np.array(tx_im),cmap="gray",vmin=0,vmax=255)
# create an instance of the qpsk modulation scheme
qpsk = komm.PSKModulation(4, phase_offset=np.pi/4)
# maximim SNR[dB] value
max_snr = 10
num_bits = 8*Npixels
# list of additive white gaussian noise sources with SNR in range 0 to max_snr
awgn = [komm.AWGNChannel(snr=10**(x/10.)) for x in range(max_snr)]
# array to store simulated bit error ratio
ber = np.zeros(max_snr)
# array to store signal-to-noise[dB] ratio for the channel
snr = np.zeros(max_snr)
# rate 1/2 code with [0o7, 0o5] as the feedforward polynomial
code,tblen = FEC.ConvCode.create_conv_codes()
# flatten the image into a 1D array and
# append tblen zeros to compensate for the decoder delay
tx_bin = np.append(np.unpackbits(np.array(tx_im)), np.zeros(tblen))
# simulate channel encoding
encoder = komm.ConvolutionalStreamEncoder(code)
code_word = encoder(tx_bin)
# simulate modulation
tx_data = qpsk.modulate(code_word)
# list containing decoding decision methods
d = args.d
decoder = komm.ConvolutionalStreamDecoder(code, traceback_length=tblen, input_type=d)
string = " ".join([d, "decoding"])
print(" ".join(["Simulating", string, "..."]))
# loop to to simulate transmission with the SNR value in range 0 to max_snr
for dB in range(max_snr):
# simulate noise in channel
rx_data = awgn[dB](tx_data)
# simulate demodulation
rx_demod = qpsk.demodulate(rx_data, decision_method=d)
# simulate channel decoding
rx_bin = decoder(rx_demod)
# total number of errors after discarding first tblen bits of rx_bin
num_error = np.sum(rx_bin[tblen:] != tx_bin[:-tblen])
# simulated BER for corresponding SNR[dB]
ber[dB] = num_error / num_bits
nonzero_index = np.nonzero(ber) # indices up to non-zero BER
snr[dB] = dB
# plot simulated BER against SNR for all the Convolutional codes
plt.figure(2)
plt.scatter(snr[nonzero_index], ber[nonzero_index])
plt.plot(snr[nonzero_index], ber[nonzero_index], label = string)
plt.yscale('log')
plt.grid(True)
plt.xlabel('SNR [dB]')
plt.ylabel('BER')
plt.legend(loc = 'upper right')
plt.title('BER against SNR Comparison (with Convolutional Code)')
plt.show()