def validate_subcarrier_location(alpha, M, K, overlap, oversampling_factor): goofy_ordering = False taps = gfdm_filter_taps('rrc', alpha, M, K, oversampling_factor) A0 = gfdm_modulation_matrix(taps, M, K, oversampling_factor, group_by_subcarrier=goofy_ordering) n = np.arange(M * K * oversampling_factor, dtype=np.complex) for k in range(K): f = np.exp(1j * 2 * np.pi * (float(k) / (K * oversampling_factor)) * n) F = abs(np.fft.fft(f)) fm = 1. * np.argmax(F) / M data = get_zero_f_data(k, K, M) x0 = gfdm_gr_modulator( data, 'rrc', alpha, M, K, overlap, compat_mode=goofy_ordering) * (2. / K) f0 = 1. * np.argmax(abs(np.fft.fft(x0))) / M xA = A0.dot( get_data_matrix( data, K, group_by_subcarrier=goofy_ordering).flatten()) * (1. / K) fA = 1. * np.argmax(abs(np.fft.fft(xA))) / M if not fm == fA == f0: raise RuntimeError( 'ERROR: subcarriers are not located at the same bins!')
def compare_subcarrier_location(alpha, M, K, overlap, oversampling_factor): import matplotlib.pyplot as plt import matplotlib.cm as cm goofy_ordering = False taps = gfdm_filter_taps('rrc', alpha, M, K, oversampling_factor) A0 = gfdm_modulation_matrix(taps, M, K, oversampling_factor, group_by_subcarrier=goofy_ordering) n = np.arange(M * K * oversampling_factor, dtype=np.complex) colors = iter(cm.rainbow(np.linspace(0, 1, K))) for k in range(K): color = next(colors) f = np.exp(1j * 2 * np.pi * (float(k) / (K * oversampling_factor)) * n) F = abs(np.fft.fft(f)) fm = np.argmax(F) / M plt.plot(F, '-.', label=k, color=color) data = get_zero_f_data(k, K, M) x0 = gfdm_gr_modulator(data, 'rrc', alpha, M, K, overlap, compat_mode=goofy_ordering) * (2. / K) f0 = 1. * np.argmax(abs(np.fft.fft(x0))) / M plt.plot(abs(np.fft.fft(x0)), label='FFT' + str(k), color=color) xA = A0.dot(get_data_matrix(data, K, group_by_subcarrier=goofy_ordering).flatten()) * (1. / K) fA = np.argmax(abs(np.fft.fft(xA))) / M plt.plot(abs(np.fft.fft(xA)), '-', label='matrix' + str(k), color=color) print fm, fA, f0 plt.legend() plt.show()
def implementation_validation(): M = 33 K = 32 alpha = .5 overlap = 2 H = get_frequency_domain_filter('rrc', alpha, M, K, overlap) taps = gfdm_filter_taps('rrc', alpha, M, K, 1) A = gfdm_modulation_matrix(taps, M, K) tests = 100 max_rel_error = 0.0 for t in range(tests): d = get_random_samples(M * K) xmat = A.dot(d) / np.sqrt(len(d)) D = get_data_matrix(d, K, group_by_subcarrier=True) xfft = gfdm_modulate_block(D, H, M, K, overlap, False) / np.sqrt( len(d)) rel_err = np.linalg.norm(xmat - xfft) / np.linalg.norm(xmat) if rel_err > max_rel_error: max_rel_error = rel_err if rel_err > 1e-3: raise RuntimeError( 'Relative error between FFT and Matrix implementation is above 1e-3!' ) print 'maximum relative error is:', max_rel_error
def main(): ''' This is a comparison for 3 different demodulation approaches. matched filter matrix being the 'benchmark' The other two should converge towards the matrix approach for overlap -> subcarriers Actually, there's a bug in the 'GR' approach, thus it only works for overlap==2 ''' timeslots = 25 subcarriers = 16 overlap = 2 time_taps = gfdm_filter_taps('rrc', .5, timeslots, subcarriers, 1) freq_taps = gfdm_freq_taps(time_taps) sparse_freq_taps = gfdm_freq_taps_sparse(freq_taps, timeslots, overlap) A = gfdm_modulation_matrix(time_taps, timeslots, subcarriers, 1, True) Ainv = np.linalg.inv(A) Amf = np.conjugate(A).T tx_syms = get_random_qpsk(timeslots * subcarriers) rx_syms = A.dot(tx_syms) mf_matrix_rx = Amf.dot(rx_syms) inv_matrix_rx = Ainv.dot(rx_syms) gr_res = gfdm_demodulate_block(rx_syms, sparse_freq_taps, subcarriers, timeslots, overlap) fft_res = gfdm_demodulate_fft_loop(rx_syms, timeslots, subcarriers, overlap, sparse_freq_taps) mf_matrix_rx *= np.sqrt( calculate_average_signal_energy(fft_res) / calculate_average_signal_energy(mf_matrix_rx)) inv_matrix_rx *= np.sqrt( calculate_average_signal_energy(fft_res) / calculate_average_signal_energy(inv_matrix_rx)) gr_res *= np.sqrt( calculate_average_signal_energy(fft_res) / calculate_average_signal_energy(gr_res)) print 'compare demodulation accuracy for different approaches' for e in range(11): em = 10**(-1. * e) matrixvsloop = np.all(np.abs(fft_res - mf_matrix_rx) < em) grvsmatrix = np.all(np.abs(gr_res - mf_matrix_rx) < em) grvsloop = np.all(np.abs(gr_res - fft_res) < em) print 'error margin {:.1e}\tMFmatriXvsGR: {}\tMFmatriXvsLoop: {}\tGRvsLoop: {}'.format( em, grvsmatrix, matrixvsloop, grvsloop)
def preamble_auto_corr_test(): K = 32 pn_seq = get_random_qpsk(K) pn_symbols = np.tile(pn_seq, 2) D = get_data_matrix(pn_symbols, K, True) # print np.shape(D) print 'subcarriers bear same symbols:', np.all(D[0] == D[1]) pl, p = generate_sync_symbol(pn_seq, 'rrc', .5, K, 2, K, K / 2) # print np.shape(p) acc = auto_correlate_halfs(p) print acc, np.angle(acc) taps = gfdm_filter_taps('rrc', .5, 2, K, 1) A = gfdm_modulation_matrix(taps, 2, K) x = A.dot(pn_symbols) # print np.shape(x) acc = auto_correlate_halfs(x) print acc, np.angle(acc)
def preamble_auto_corr_test(): K = 32 pn_seq = get_random_qpsk(K) pn_symbols = np.tile(pn_seq, 2) D = get_data_matrix(pn_symbols, K, True) # print np.shape(D) print 'subcarriers bear same symbols:', np.all(D[0] == D[1]) pl, p = generate_sync_symbol(pn_seq, 'rrc', .5, K, 2, K, K / 2) # print np.shape(p) acc = auto_correlate_halfs(p) print acc, np.angle(acc) taps = gfdm_filter_taps('rrc', .5, 2, K, 1) A = gfdm_modulation_matrix(taps, 2, K) x = A.dot(pn_symbols) # print np.shape(x) acc = auto_correlate_halfs(x) print acc, np.angle(acc)
def validate_subcarrier_location(alpha, M, K, overlap, oversampling_factor): goofy_ordering = False taps = gfdm_filter_taps('rrc', alpha, M, K, oversampling_factor) A0 = gfdm_modulation_matrix(taps, M, K, oversampling_factor, group_by_subcarrier=goofy_ordering) n = np.arange(M * K * oversampling_factor, dtype=np.complex) for k in range(K): f = np.exp(1j * 2 * np.pi * (float(k) / (K * oversampling_factor)) * n) F = abs(np.fft.fft(f)) fm = 1. * np.argmax(F) / M data = get_zero_f_data(k, K, M) x0 = gfdm_gr_modulator(data, 'rrc', alpha, M, K, overlap, compat_mode=goofy_ordering) * (2. / K) f0 = 1. * np.argmax(abs(np.fft.fft(x0))) / M xA = A0.dot(get_data_matrix(data, K, group_by_subcarrier=goofy_ordering).flatten()) * (1. / K) fA = 1. * np.argmax(abs(np.fft.fft(xA))) / M if not fm == fA == f0: raise RuntimeError('ERROR: subcarriers are not located at the same bins!')
def implementation_validation(): M = 33 K = 32 alpha = .5 overlap = 2 H = get_frequency_domain_filter('rrc', alpha, M, K, overlap) taps = gfdm_filter_taps('rrc', alpha, M, K, 1) A = gfdm_modulation_matrix(taps, M, K) tests = 100 max_rel_error = 0.0 for t in range(tests): d = get_random_samples(M * K) xmat = A.dot(d) / np.sqrt(len(d)) D = get_data_matrix(d, K, group_by_subcarrier=True) xfft = gfdm_modulate_block(D, H, M, K, overlap, False) / np.sqrt(len(d)) rel_err = np.linalg.norm(xmat - xfft) / np.linalg.norm(xmat) if rel_err > max_rel_error: max_rel_error = rel_err if rel_err > 1e-3: raise RuntimeError('Relative error between FFT and Matrix implementation is above 1e-3!') print 'maximum relative error is:', max_rel_error
def main(): ''' This is a comparison for 3 different demodulation approaches. matched filter matrix being the 'benchmark' The other two should converge towards the matrix approach for overlap -> subcarriers Actually, there's a bug in the 'GR' approach, thus it only works for overlap==2 ''' timeslots = 25 subcarriers = 16 overlap = 2 time_taps = gfdm_filter_taps('rrc', .5, timeslots, subcarriers, 1) freq_taps = gfdm_freq_taps(time_taps) sparse_freq_taps = gfdm_freq_taps_sparse(freq_taps, timeslots, overlap) A = gfdm_modulation_matrix(time_taps, timeslots, subcarriers, 1, True) Ainv = np.linalg.inv(A) Amf = np.conjugate(A).T tx_syms = get_random_qpsk(timeslots * subcarriers) rx_syms = A.dot(tx_syms) mf_matrix_rx = Amf.dot(rx_syms) inv_matrix_rx = Ainv.dot(rx_syms) gr_res = gfdm_demodulate_block(rx_syms, sparse_freq_taps, subcarriers, timeslots, overlap) fft_res = gfdm_demodulate_fft_loop(rx_syms, timeslots, subcarriers, overlap, sparse_freq_taps) mf_matrix_rx *= np.sqrt(calculate_average_signal_energy(fft_res) / calculate_average_signal_energy(mf_matrix_rx)) inv_matrix_rx *= np.sqrt(calculate_average_signal_energy(fft_res) / calculate_average_signal_energy(inv_matrix_rx)) gr_res *= np.sqrt(calculate_average_signal_energy(fft_res) / calculate_average_signal_energy(gr_res)) print 'compare demodulation accuracy for different approaches' for e in range(11): em = 10 ** (-1. * e) matrixvsloop = np.all(np.abs(fft_res - mf_matrix_rx) < em) grvsmatrix = np.all(np.abs(gr_res - mf_matrix_rx) < em) grvsloop = np.all(np.abs(gr_res - fft_res) < em) print 'error margin {:.1e}\tMFmatriXvsGR: {}\tMFmatriXvsLoop: {}\tGRvsLoop: {}'.format(em, grvsmatrix, matrixvsloop, grvsloop)