├── MC_AE.py ├── README.md ├── models ├── decoder_N4M16.h5 ├── decoder_N4M16_.h5 ├── encoder_N4M16.h5 └── encoder_N4M16_.h5 ├── plot_constellation ├── coding_gain.py ├── cons_data │ ├── cons_N2M4.mat │ ├── cons_N2M4_awgn.mat │ ├── cons_N2M8.mat │ ├── cons_N3M16.mat │ ├── cons_N3M8.mat │ ├── cons_N4M16.mat │ ├── cons_N4M256.mat │ ├── cons_OFDM_IM_N2K1M4.mat │ ├── cons_OFDM_IM_N4K1M4.mat │ ├── cons_OFDM_IM_N4K3M4.mat │ ├── cons_S_OFDM_IM_N2K1M2.mat │ ├── cons_S_OFDM_IM_N2K1M4.mat │ ├── cons_S_OFDM_IM_N4K1M4.mat │ ├── cons_S_OFDM_IM_N4K3M4.mat │ ├── cons_S_OFDM_N4M2.mat │ ├── cons_S_OFDM_N4M4.mat │ └── cons_xx.mat ├── cons_figs │ ├── cons_N2M4.png │ ├── cons_N2M4_awgn.png │ ├── cons_N2M8.png │ ├── cons_N4M16.png │ └── cons_N4M256.png ├── euclidean_distance.py ├── plot_constellations_N2M4.py ├── plot_constellations_N2M8.py ├── plot_constellations_N4M16.py └── plot_constellations_N4M256.py └── utils.py /MC_AE.py: -------------------------------------------------------------------------------- 1 | """ 2 | - This is the implementation of MC-AE under Rayleigh fading channel 3 | - Requirements: tensorflow 1.15, keras 2.0.8 4 | - Created by Thien Van Luong, Research Fellow at University of Southampton, UK. 5 | - Email: thien.luong@soton.ac.uk. 6 | """ 7 | from utils import generate_one_hot_vectors, calculate_coding_gain 8 | import tensorflow as tf 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | from keras.layers import Lambda, Add, Reshape, Dense, Flatten, Input 12 | from keras.models import Model, load_model 13 | from keras.optimizers import Adam 14 | from keras import backend as K 15 | 16 | # ----------------- MC-AE parameters setup --------------------------- 17 | N = 4 # number of subcarriers 18 | M = 16 # total modulation size 19 | m = int(np.log2(M)) # bits per codeword/block of N subcarriers 20 | R = m/N # bit rate - bits/s/Hz 21 | 22 | # neural network config for training and testing 23 | SNRdB_train = 7 # training SNR 24 | b_size = 512 # batch_size 25 | pre_trained = False # use pre-trained model or not 26 | norm_type = 0 # 0 per sample norm, 1 per batch norm 27 | n_epoch = 100 # number of epochs 28 | l_rate = 0.001 # learning rate 29 | hidden_layer_dec = np.array([256]) # number of nodes of hidden layers in decoder 30 | f_loss = 'mean_squared_error' # categorical_crossentropy/ mean_squared_error loss function 31 | train_size = 20000 # number of training data samples 32 | test_size = 20000 # number of testing data samples 33 | act_enc = 'linear' # activation used in the encoder 34 | act_dec = 'relu' # activation used in the decoder 35 | ini = 'normal' # weight initialization method 36 | 37 | 38 | snr_train = 10**(SNRdB_train/10.0) 39 | noise_std = np.sqrt(1/(2*R*snr_train)) 40 | 41 | """==== build channel layers for training and testing ====""" 42 | # training channel layer 43 | def channel(Z): 44 | # eps_train = 1/(1+10**2) # trained with imperfect CSI 45 | eps_train = 0 46 | 47 | H_est = K.random_normal(K.shape(Z),mean=0,stddev=np.sqrt(1-eps_train))/np.sqrt(2) 48 | H_R_est = H_est[:,:,0] 49 | H_I_est = H_est[:,:,1] 50 | err = K.random_normal(K.shape(Z), mean=0, stddev=np.sqrt(eps_train))/np.sqrt(2) 51 | 52 | H = H_est + err 53 | 54 | H_R = H[:,:,0] 55 | H_I = H[:,:,1] 56 | real = H_R * Z[:,:,0] - H_I* Z[:,:,1] 57 | imag = H_R * Z[:,:,1] + H_I* Z[:,:,0] 58 | 59 | noise_r = K.random_normal(K.shape(real),mean=0,stddev=noise_std) 60 | noise_i = K.random_normal(K.shape(imag),mean=0,stddev=noise_std) 61 | 62 | real = Add()([real, noise_r]) 63 | imag = Add()([imag, noise_i]) 64 | 65 | Y = K.stack([real, imag, H_R_est, H_I_est], axis=2) 66 | return Y 67 | 68 | # testing channel layer 69 | def channel_test(Z, noise_std, test_size, imperfect_channel=False): 70 | eps = 0 71 | if imperfect_channel: 72 | snr = noise_std*noise_std*2*R 73 | eps = 1/(1+1/snr) # imperfect CSI 74 | 75 | H_R_est = np.random.normal(0, np.sqrt(1-eps), (test_size, N))/np.sqrt(2) 76 | H_I_est = np.random.normal(0, np.sqrt(1-eps), (test_size, N))/np.sqrt(2) 77 | 78 | err_r = K.random_normal(K.shape(Z[:,:,0]), mean=0, stddev=np.sqrt(eps))/np.sqrt(2) 79 | err_i = K.random_normal(K.shape(Z[:,:,1]), mean=0, stddev=np.sqrt(eps))/np.sqrt(2) 80 | 81 | H_R = H_R_est + err_r 82 | H_I = H_I_est + err_i 83 | 84 | real = H_R*Z[:,:,0] - H_I*Z[:,:,1] # x.shape (50000, 2, 2) 85 | imag = H_R*Z[:,:,1] + H_I*Z[:,:,0] 86 | 87 | noise_r = K.random_normal(K.shape(real), mean=0, stddev=noise_std) 88 | noise_i = K.random_normal(K.shape(imag), mean=0, stddev=noise_std) 89 | 90 | real = real + noise_r 91 | imag = imag + noise_i 92 | 93 | Y = K.stack([real, imag, H_R_est, H_I_est], axis=2) 94 | Y = tf.Session().run(Y) 95 | 96 | return Y 97 | 98 | """======= build MC-AE autoecoder model ==============""" 99 | # encoder 100 | X = Input(shape=(M,)) 101 | enc = Dense(2*N, use_bias=True, activation=act_enc, init=ini)(X) # be careful 102 | if norm_type == 0: 103 | enc = Lambda(lambda x: np.sqrt(N) * K.l2_normalize(x, axis=1))(enc) 104 | else: 105 | enc = Lambda(lambda x: x/tf.sqrt(2*tf.reduce_mean(tf.square(x))))(enc) 106 | Z = Reshape((-1,2))(enc) # output of encoder or transmitted vector 107 | 108 | # Y is input of decoder, Y may include received signal y=hx+n and channel h 109 | Y = Lambda(lambda x: channel(x))(Z) 110 | 111 | # decoder 112 | n_hidden_layer_dec = len(hidden_layer_dec) 113 | dec = Flatten()(Y) 114 | for n in range(n_hidden_layer_dec): 115 | dec = Dense(hidden_layer_dec[n], activation=act_dec, init=ini)(dec) 116 | 117 | X_hat = Dense(M, activation='softmax', init=ini)(dec) # estimate of X 118 | 119 | # model encoder and decoder 120 | AE = Model(X,X_hat) 121 | encoder = Model(X,Z) 122 | 123 | X_enc = Input(shape=(N,4,)) 124 | deco = AE.layers[-n_hidden_layer_dec-2](X_enc) # first layer of decoder 125 | for n in range(n_hidden_layer_dec+1): # hidden and last layers of decoder 126 | deco = AE.layers[-n_hidden_layer_dec-1+n](deco) 127 | decoder = Model(X_enc, deco) 128 | 129 | # training or loading pre-trained model 130 | if not pre_trained: 131 | train_data = generate_one_hot_vectors(M, train_size, get_label=False) 132 | AE.compile(optimizer=Adam(lr=l_rate), loss=f_loss) 133 | AE.fit(train_data, train_data, epochs=n_epoch, batch_size=b_size, verbose=2) 134 | encoder.save_weights('./models/encoder_N4M16_.h5') 135 | decoder.save_weights('./models/decoder_N4M16_.h5') 136 | else: 137 | encoder.load_weights('./models/encoder_N4M16.h5') 138 | decoder.load_weights('./models/decoder_N4M16.h5') 139 | 140 | 141 | # Coding gain calculation 142 | test_label = np.arange(M) 143 | test_data = [] 144 | for i in test_label: 145 | temp = np.zeros(M) 146 | temp[i] = 1 147 | test_data.append(temp) 148 | test_data = np.array(test_data) 149 | U = encoder.predict(test_data) 150 | V = U.view(dtype=np.complex64) # learned transmitted codewords 151 | # print(V) 152 | print('Coding gain = ', calculate_coding_gain(U)) 153 | 154 | # test data 155 | test_data, test_label = generate_one_hot_vectors(M, test_size, get_label=True) 156 | test_bit = (((test_label[:,None] & (1 << np.arange(m)))) > 0).astype(int) 157 | 158 | # BLER calculation and plot 159 | print('\nPerfect CSI BLER') 160 | EbNodB_range = list(np.linspace(0, 25, 6)) 161 | BER = [None] * len(EbNodB_range) 162 | BLER = [None] * len(EbNodB_range) 163 | for n in range(0, len(EbNodB_range)): 164 | EbNo = 10 ** (EbNodB_range[n] / 10.0) 165 | noise_std = np.sqrt(1/(2*R*EbNo)) 166 | 167 | no_errors = 0 168 | Z = encoder.predict(test_data) 169 | Y = channel_test(Z,noise_std,test_size,imperfect_channel=False) 170 | X_hat = decoder.predict(Y) 171 | pred_output = np.argmax(X_hat, axis=1) 172 | 173 | re_bit = (((pred_output[:, None] & (1 << np.arange(m)))) > 0).astype(int) 174 | bit_errors = (re_bit != test_bit).sum() 175 | BER[n] = bit_errors / test_size / m 176 | 177 | block_errors = (pred_output != test_label) 178 | block_errors = block_errors.astype(int).sum() 179 | BLER[n] = block_errors / test_size 180 | print('SNR:', EbNodB_range[n], 'BER:', BER[n], 'BLER:', BLER[n]) 181 | 182 | bler = BLER 183 | 184 | # BLER calculation and plot for imperfect CSI 185 | print('\nImperfect CSI BLER') 186 | EbNodB_range = list(np.linspace(0, 25, 6)) 187 | BER = [None] * len(EbNodB_range) 188 | BLER = [None] * len(EbNodB_range) 189 | for n in range(0, len(EbNodB_range)): 190 | EbNo = 10 ** (EbNodB_range[n] / 10.0) 191 | noise_std = np.sqrt(1 / (2 * R * EbNo)) 192 | 193 | no_errors = 0 194 | Z = encoder.predict(test_data) 195 | Y = channel_test(Z, noise_std, test_size, imperfect_channel=True) 196 | X_hat = decoder.predict(Y) 197 | pred_output = np.argmax(X_hat, axis=1) 198 | no_errors = (pred_output != test_label) 199 | no_errors = no_errors.astype(int).sum() 200 | BLER[n] = no_errors / test_size 201 | print('SNR:', EbNodB_range[n], 'BLER:', BLER[n]) 202 | 203 | bler_im = BLER 204 | # plot BLER 205 | plt.plot(EbNodB_range, bler,'bo-', label='MC-AE under perfect CSI') 206 | plt.plot(EbNodB_range, bler_im,'r+-', label='MC-AE under imperfect CSI') 207 | plt.yscale('log') 208 | plt.xlabel('SNR (dB)') 209 | plt.ylabel('BLER') 210 | plt.title('MC-AE with (M,N)=('+str(N)+','+str(M)+')') 211 | plt.legend() 212 | plt.grid() 213 | plt.show() 214 | 215 | # plot learned MC-AE constellations 216 | n1=0 217 | n2=1 218 | n3=2 219 | n4=3 220 | fig = plt.figure(figsize=(4,4)) 221 | 222 | if (N==4): 223 | plt.plot(U[:,n1,0], U[:,n1,1], "b.") 224 | plt.plot(U[:,n2,0], U[:,n2,1], "r*") 225 | plt.plot(U[:,n3,0], U[:,n3,1], "go") 226 | plt.plot(U[:,n4,0], U[:,n4,1], "k+") 227 | elif N==2: 228 | plt.plot(U[:,n1,0], U[:,n1,1], "b.") 229 | plt.plot(U[:,n2,0], U[:,n2,1], "r*") 230 | else: 231 | plt.plot(U[:,n1,0], U[:,n1,1], "b.") 232 | plt.plot(U[:,n2,0], U[:,n2,1], "r*") 233 | plt.plot(U[:,n3,0], U[:,n3,1], "go") 234 | plt.grid(True) 235 | plt.title('MC-AE constellation') 236 | plt.show() 237 | 238 | # save learned codewords 239 | import scipy.io 240 | scipy.io.savemat('.\plot_constellation\cons_data\cons_xx.mat', dict(U=U)) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multicarrier Autoencoder 2 | This is the first implementation of multicarrier autoencoder communication systems in the following paper: 3 | 4 | T. V. Luong, Y. Ko and et. al, "Deep learning aided multicarrier systems", IEEE Trans. Wireless Commun., Nov., 2020 (Accepted). https://ieeexplore.ieee.org/abstract/document/9271932 5 | 6 | Please use the files in folder ./plot_constellation to: 7 | - Calculate coding gains for the proposed MC-AE and baselines whose constellation data is saved in folder ./plot_constellation/cons_data. 8 | - Plot constellations for various MC-AE parameters N and M, as well as constellation of the baselines. 9 | - Calculate the minimum Enclidean distance (MED) for learned codewords of MC-AE. 10 | 11 | The BLER of MC-AE can be quickly obtained by running the pre-trained model stored in folder ./models. 12 | 13 | The main file of MC-AE is MC_AE.py. 14 | 15 | Requirements: 16 | - Tensorflow 1.15, Keras 2.0.8. 17 | - Others: Numpy, scipy, matplotlib. 18 | 19 | Note that further files for multi-user MC-AE systems, Emb-MC-AE, and the baselines will be updated soon. 20 | -------------------------------------------------------------------------------- /models/decoder_N4M16.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienVanLuong/multicarrier_autoencoder/790a72dfd3896e0e423d99426db3f3f9af78c2fc/models/decoder_N4M16.h5 -------------------------------------------------------------------------------- /models/decoder_N4M16_.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienVanLuong/multicarrier_autoencoder/790a72dfd3896e0e423d99426db3f3f9af78c2fc/models/decoder_N4M16_.h5 -------------------------------------------------------------------------------- /models/encoder_N4M16.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienVanLuong/multicarrier_autoencoder/790a72dfd3896e0e423d99426db3f3f9af78c2fc/models/encoder_N4M16.h5 -------------------------------------------------------------------------------- /models/encoder_N4M16_.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThienVanLuong/multicarrier_autoencoder/790a72dfd3896e0e423d99426db3f3f9af78c2fc/models/encoder_N4M16_.h5 -------------------------------------------------------------------------------- /plot_constellation/coding_gain.py: -------------------------------------------------------------------------------- 1 | import scipy.io as sio 2 | import numpy as np 3 | 4 | 5 | # data = sio.loadmat("./cons_data/cons_S_OFDM_IM_N2K1M4.mat") 6 | data = sio.loadmat("./cons_data/cons_N4M16.mat") 7 | 8 | U = data['U'] 9 | V = U[:,:,0] + 1j*U[:,:,1] 10 | print('Codewords: \n', np.round(V,4)) 11 | 12 | M = len(V) 13 | N = V.shape[1] 14 | Gd = N 15 | 16 | Gc = 10000 17 | sum_Gc = 0 18 | for n1 in range(M): 19 | for n2 in range(n1+1,M): 20 | Y = np.prod(np.power(np.abs(V[n1]-V[n2]),2)) 21 | sum_Gc = sum_Gc + 1/Y 22 | if (Yi: 16 | dis_ij = np.sqrt(np.sum(np.abs(V[j]-V[i])*np.abs(V[j]-V[i]))) 17 | dis.append(dis_ij) 18 | 19 | print('\nMinimum distance: ', min(dis)) 20 | print('\nAll distances: ', np.round(dis,2)) 21 | -------------------------------------------------------------------------------- /plot_constellation/plot_constellations_N2M4.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | import scipy.io as sio 4 | 5 | 6 | # data = sio.loadmat("./cons_data/cons_N2M4_awgn.mat") 7 | data = sio.loadmat("./cons_data/cons_N2M4.mat") 8 | U4 = data['U'] 9 | 10 | U3 = np.array([[1,-1, 0, 0], [0, 0, -1, 1]]) #S-OFDM-IM 11 | U1 = np.array([[1,-1], [0, 0]]) #OFDM 12 | U2 = np.sqrt(1)*np.array([[1,-1, 0], [0, 0, 0]]) #OFDM-IM 13 | 14 | marker_size = 16 15 | 16 | # fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True, figsize=(8, 8)) 17 | fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True, figsize=(8, 8)) 18 | 19 | 20 | ax4.plot(U4[:,0,0], U4[:,0,1], "b.", markersize=marker_size) 21 | ax4.plot(U4[:,1,0], U4[:,1,1], "rx", markersize=marker_size) 22 | major_ticks = np.arange(-1, 2, 0.5) 23 | ax4.set_xticks(major_ticks) 24 | ax4.set_yticks(major_ticks) 25 | ax4.grid(True) 26 | ax4.set_title('Proposed MC-AE', fontsize=12) 27 | 28 | ax3.plot(U3[0,:], U3[1,:], "b.", markersize=marker_size) 29 | ax3.plot(U3[0,:], U3[1,:], "rx", markersize=marker_size) 30 | ax3.grid(True) 31 | ax3.set_title('S-OFDM/S-OFDM-IM', fontsize=12) 32 | 33 | ax1.plot(U1[0,:], U1[1,:], "b.", markersize=marker_size) 34 | ax1.plot(U1[0,:], U1[1,:], "rx", markersize=marker_size) 35 | ax1.grid(True) 36 | ax1.set_title('OFDM') 37 | 38 | ax2.plot(U2[0,:], U2[1,:], "b.", markersize=marker_size) 39 | ax2.plot(U2[0,:], U2[1,:], "rx", markersize=marker_size) 40 | ax2.grid(True) 41 | ax2.set_title('OFDM-IM') 42 | 43 | # fig.suptitle('Contellation for N=2 M=4', fontsize=12) 44 | fig.savefig('./cons_figs/cons_N2M4xx.png',dpi=100) 45 | plt.show() -------------------------------------------------------------------------------- /plot_constellation/plot_constellations_N2M8.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | import scipy.io as sio 4 | 5 | data = sio.loadmat("./cons_data/cons_N2M8.mat") 6 | U3 = data['U'] 7 | 8 | data = sio.loadmat("./cons_data/cons_S_OFDM_IM_N2K1M4.mat") 9 | U2 = data['U'] 10 | 11 | data = sio.loadmat("./cons_data/cons_OFDM_IM_N2K1M4.mat") 12 | U1 = data['U'] 13 | 14 | marker_size = 16 15 | 16 | fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, sharex=True, sharey=True, figsize=(10, 3)) 17 | 18 | ax1.plot(U1[:,0,0], U1[:,0,1], "b.", markersize=marker_size) 19 | ax1.plot(U1[:,1,0], U1[:,1,1], "rx", markersize=marker_size) 20 | ax1.grid(True) 21 | ax1.set_title('OFDM-IM', fontsize=14) 22 | 23 | 24 | ax2.plot(U2[:,0,0], U2[:,0,1], "b.", markersize=marker_size) 25 | ax2.plot(U2[:,1,0], U2[:,1,1], "rx", markersize=marker_size) 26 | ax2.grid(True) 27 | ax2.set_title('S-OFDM-IM', fontsize=14) 28 | 29 | 30 | 31 | ax3.plot(U3[:,0,0], U3[:,0,1], "b.", markersize=marker_size) 32 | ax3.plot(U3[:,1,0], U3[:,1,1], "rx", markersize=marker_size) 33 | major_ticks = np.arange(-1, 2, 1) 34 | ax3.set_xticks(major_ticks) 35 | ax3.set_yticks(major_ticks) 36 | ax3.grid(True) 37 | ax3.set_title('Proposed MC-AE', fontsize=14) 38 | 39 | 40 | # fig.suptitle('Contellation for N=2 M=4', fontsize=12) 41 | fig.savefig('./cons_figs/cons_N2M8.png',dpi=100) 42 | plt.show() -------------------------------------------------------------------------------- /plot_constellation/plot_constellations_N4M16.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | import scipy.io as sio 4 | 5 | data = sio.loadmat("./cons_data/cons_N4M16.mat") 6 | U4 = data['U'] 7 | 8 | data = sio.loadmat("./cons_data/cons_S_OFDM_N4M2.mat") 9 | U2 = data['U'] 10 | 11 | data = sio.loadmat("./cons_data/cons_S_OFDM_IM_N4K1M4.mat") 12 | U3 = data['U'] 13 | 14 | data = sio.loadmat("./cons_data/cons_OFDM_IM_N4K1M4.mat") 15 | U1 = data['U'] 16 | 17 | marker_size = 16 18 | 19 | fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True, figsize=(8, 8)) 20 | 21 | ax1.plot(U1[:,0,0], U1[:,0,1], "b.", markersize=marker_size) 22 | ax1.plot(U1[:,1,0], U1[:,1,1], "rx", markersize=marker_size) 23 | ax1.grid(True) 24 | ax1.set_title('OFDM-IM') 25 | 26 | 27 | ax2.plot(U2[:,0,0], U2[:,0,1], "b.", markersize=marker_size) 28 | ax2.plot(U2[:,1,0], U2[:,1,1], "rx", markersize=marker_size) 29 | ax2.grid(True) 30 | ax2.set_title('S-OFDM') 31 | 32 | 33 | ax3.plot(U3[:,0,0], U3[:,0,1], "b.", markersize=marker_size) 34 | ax3.plot(U3[:,1,0], U3[:,1,1], "rx", markersize=marker_size) 35 | ax3.grid(True) 36 | ax3.set_title('S-OFDM-IM', fontsize=12) 37 | 38 | ax4.plot(U4[:,0,0], U4[:,0,1], "b.", markersize=marker_size) 39 | ax4.plot(U4[:,1,0], U4[:,1,1], "rx", markersize=marker_size) 40 | major_ticks = np.arange(-1, 2, 1) 41 | ax4.set_xticks(major_ticks) 42 | ax4.set_yticks(major_ticks) 43 | ax4.grid(True) 44 | ax4.set_title('Proposed MC-AE', fontsize=12) 45 | 46 | 47 | # fig.suptitle('Contellation for N=2 M=4', fontsize=12) 48 | fig.savefig('./cons_figs/cons_N4M16.png',dpi=100) 49 | plt.show() -------------------------------------------------------------------------------- /plot_constellation/plot_constellations_N4M256.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | import numpy as np 3 | import scipy.io as sio 4 | 5 | data = sio.loadmat("cons_N4M256.mat") 6 | U4 = data['U'] 7 | 8 | 9 | data = sio.loadmat("Cons_S_OFDM_N4M4.mat") 10 | U2 = data['U'] 11 | 12 | data = sio.loadmat("Cons_S_OFDM_IM_N4K3M4.mat") 13 | U3 = data['U'] 14 | 15 | data = sio.loadmat("Cons_OFDM_IM_N4K3M4.mat") 16 | U1 = data['U'] 17 | 18 | marker_size = 12 19 | 20 | fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True, figsize=(8, 8)) 21 | 22 | ax1.plot(U1[:,0,0], U1[:,0,1], "b.", markersize=marker_size) 23 | ax1.plot(U1[:,1,0], U1[:,1,1], "rx", markersize=marker_size) 24 | ax1.grid(True) 25 | ax1.set_title('OFDM-IM') 26 | 27 | 28 | ax2.plot(U2[:,0,0], U2[:,0,1], "b.", markersize=marker_size) 29 | ax2.plot(U2[:,1,0], U2[:,1,1], "rx", markersize=marker_size) 30 | ax2.grid(True) 31 | ax2.set_title('S-OFDM') 32 | 33 | 34 | ax3.plot(U3[:,0,0], U3[:,0,1], "b.", markersize=marker_size) 35 | ax3.plot(U3[:,1,0], U3[:,1,1], "rx", markersize=marker_size) 36 | ax3.grid(True) 37 | ax3.set_title('S-OFDM-IM', fontsize=12) 38 | 39 | ax4.plot(U4[:,0,0], U4[:,0,1], "b.", markersize=marker_size) 40 | ax4.plot(U4[:,1,0], U4[:,1,1], "rx", markersize=marker_size) 41 | major_ticks = np.arange(-1, 2, 1) 42 | ax4.set_xticks(major_ticks) 43 | ax4.set_yticks(major_ticks) 44 | ax4.grid(True) 45 | ax4.set_title('Proposed Emb-MC-AE', fontsize=12) 46 | 47 | 48 | 49 | 50 | # fig.suptitle('Contellation for N=2 M=4', fontsize=12) 51 | fig.savefig('cons_N4M256.png',dpi=100) 52 | plt.show() -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | # generate data, one-hot vector 4 | def generate_one_hot_vectors(M, data_size, get_label=False): 5 | """ 6 | Generate one hot vectors which are used as training data or testing data. 7 | 8 | Parameters: 9 | ----- 10 | M: int, dimension of one-hot vectors, i.e, number of classes/categoraries 11 | data_size: int, number of one-hot vectors generated 12 | 13 | Return: 14 | data: shape(data_size,M) array 15 | 16 | """ 17 | label = np.random.randint(M, size=data_size) 18 | data = [] 19 | for i in label: 20 | temp = np.zeros(M) 21 | temp[i] = 1 22 | data.append(temp) 23 | data = np.array(data) 24 | 25 | if not get_label: 26 | return data 27 | else: 28 | return data, label 29 | 30 | def calculate_coding_gain(U): 31 | V = U[:,:,0] + 1j*U[:,:,1] 32 | N = V.shape[1] 33 | M = V.shape[0] 34 | Gd = N # maximum diversity gain is the number of subcarriers 35 | Gc = 10000 36 | sum_Gc = 0 37 | 38 | for n1 in range(M): 39 | for n2 in range(n1+1,M): 40 | Y = np.prod(np.power(np.abs(V[n1]-V[n2]),2)) 41 | sum_Gc = sum_Gc + 1/Y 42 | if (Y