Exemple #1
0
def gfdm_rx_fft2(y, filtertype, alpha, M, K, L, N, QAM, J):
    """
    y: transmitted gfdm-block (length: M*K samples)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter
    Low-complexity receiver implementation as proposed by G.Fettweis
    (based on sparse frequency Domain Processing)

    output: demodulated samples in original order (first K samples in timeslot 1, second K ...)
    """
    h = gfdm_filter_taps(filtertype, alpha, M, K, 1)
    h = np.roll(h, h.shape[-1] / 2)
    H_rx = np.fft.fft(h)
    H_sparse = np.concatenate((H_rx[0:M * L / 2], H_rx[-M * L / 2:]))
    y_ifft = np.array([])
    y = (1.0 / K) * y
    # Transfer input to frequency domain and center around 0th frequency bin
    y_f = np.fft.fftshift(np.fft.fft(y))
    # Filter and superposition in frequency domain
    Y_fs = gfdm_rx_filsup(y_f, H_sparse, M, K, L)
    # Demodulate per subcarrier
    y_ifft = gfdm_rx_demod(Y_fs, K)
    if J > 0:
        y_ifft = gfdm_rx_sic(K, M, J, H_sparse, y_ifft, Y_fs, QAM)
        y_ifft = np.reshape(y_ifft, (K * M))
    # Sort output in timeslot,subcarrier order
    y_ifft = reshape_input(y_ifft, K, M)
    return y_ifft
Exemple #2
0
def gfdm_rx_fft2(y, filtertype, alpha, M, K, L, N, QAM, J):
    '''
    y: transmitted gfdm-block (length: M*K samples)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter
    Low-complexity receiver implementation as proposed by G.Fettweis
    (based on sparse frequency Domain Processing)

    output: demodulated samples in original order (first K samples in timeslot 1, second K ...)
    '''
    h = gfdm_filter_taps(filtertype, alpha, M, K, 1)
    h = np.roll(h, h.shape[-1] / 2)
    H_rx = np.fft.fft(h)
    H_sparse = np.concatenate((H_rx[0:M * L / 2], H_rx[-M * L / 2:]))
    y_ifft = np.array([])
    y = (1.0 / K) * y
    # Transfer input to frequency domain and center around 0th frequency bin
    y_f = np.fft.fftshift(np.fft.fft(y))
    # Filter and superposition in frequency domain
    Y_fs = gfdm_rx_filsup(y_f, H_sparse, M, K, L)
    # Demodulate per subcarrier
    y_ifft = gfdm_rx_demod(Y_fs, K)
    if J > 0:
        y_ifft = gfdm_rx_sic(K, M, J, H_sparse, y_ifft, Y_fs, QAM)
        y_ifft = np.reshape(y_ifft, (K * M))
    # Sort output in timeslot,subcarrier order
    y_ifft = reshape_input(y_ifft, K, M)
    return y_ifft
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 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
Exemple #6
0
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)
Exemple #7
0
def gfdm_tx_fft2(x, filtertype, alpha, M, K, L, N):
    '''
    x: Input-Array (length: M*K symbols)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter

    Low-complexity transmitter implementation as proposed by G. Fettweis
    '''
    h = gfdm_filter_taps(filtertype, alpha, M, K, 1)
    H = gfdm_freq_taps(h)
    H_sparse = gfdm_freq_taps_sparse(H, M, L)

    # Sort Input subcarrierwise
    x = reshape_input(x, M, K)
    x_out = np.zeros((M * K) + (L - 1) * M, dtype='complex')
    for k in xrange(K):
        # M rows and L columns with respective FFT output
        # pick symbols per subcarrier
        x_k = x[k * M:((k + 1) * M)]
        # perform fft and switch to frequency domain
        x_f = np.fft.fft(x_k)
        # copy values of M-point DFT to obtain MK-point DFT
        x_f_L = np.tile(x_f, L)
        # make data-vector 'sparse'
        # x_f_L = np.concatenate((x_f_K[0:(M*L)/2], x_f_K[-(M*L)/2:]))
        # filter with sparse filter taps in frequency domain
        x_fil = np.multiply(x_f_L, H_sparse)
        # Add data-vector to correct position -max neg frequency : 0 :
        # max_pos_frequency
        x_out[k * M:(k + L) *
              M] = x_out[k * M:(L + k) * M] + np.fft.fftshift(x_fil)
    # Add 'oversampled' parts of first subcarrier to end and 'oversampled' parts
    # of last subcarrier to start
    x_first = x_out[0:(L - 1) * M / 2]
    x_last = x_out[-(L - 1) * M / 2:]
    x_out = x_out[(L - 1) * M / 2:-(L - 1) * M / 2]
    x_out[0:(L - 1) * M / 2] = x_out[0:(L - 1) * M / 2] + x_last
    x_out[-(L - 1) * M / 2:] = x_out[-(L - 1) * M / 2:] + x_first

    x_t = np.fft.ifft(np.fft.ifftshift(x_out))
    x_t *= 1.0 / K
    return x_t
Exemple #8
0
def gfdm_tx_fft2(x, filtertype, alpha, M, K, L, N):
    '''
    x: Input-Array (length: M*K symbols)
    filtertype: ('rrc'|'rc')
    alpha: (0,1) float
    M: number of slots
    K: number of subcarriers
    L: freq-domain length of filter

    Low-complexity transmitter implementation as proposed by G. Fettweis
    '''
    h = gfdm_filter_taps(filtertype, alpha, M, K, 1)
    H = gfdm_freq_taps(h)
    H_sparse = gfdm_freq_taps_sparse(H, M, L)

    # Sort Input subcarrierwise
    x = reshape_input(x, M, K)
    x_out = np.zeros((M * K) + (L - 1) * M, dtype='complex')
    for k in xrange(K):
        # M rows and L columns with respective FFT output
        # pick symbols per subcarrier
        x_k = x[k * M:((k + 1) * M)]
        # perform fft and switch to frequency domain
        x_f = np.fft.fft(x_k)
        # copy values of M-point DFT to obtain MK-point DFT
        x_f_L = np.tile(x_f, L)
        # make data-vector 'sparse'
        # x_f_L = np.concatenate((x_f_K[0:(M*L)/2], x_f_K[-(M*L)/2:]))
        # filter with sparse filter taps in frequency domain
        x_fil = np.multiply(x_f_L, H_sparse)
        # Add data-vector to correct position -max neg frequency : 0 :
        # max_pos_frequency
        x_out[k * M:(k + L) * M] = x_out[k * M:(L + k) * M] + np.fft.fftshift(x_fil)
    # Add 'oversampled' parts of first subcarrier to end and 'oversampled' parts
    # of last subcarrier to start
    x_first = x_out[0:(L - 1) * M / 2]
    x_last = x_out[-(L - 1) * M / 2:]
    x_out = x_out[(L - 1) * M / 2:-(L - 1) * M / 2]
    x_out[0:(L - 1) * M / 2] = x_out[0:(L - 1) * M / 2] + x_last
    x_out[-(L - 1) * M / 2:] = x_out[-(L - 1) * M / 2:] + x_first

    x_t = np.fft.ifft(np.fft.ifftshift(x_out))
    x_t *= 1.0 / K
    return x_t
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)
Exemple #10
0
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)
Exemple #11
0
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!')
Exemple #12
0
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
Exemple #13
0
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)
Exemple #14
0
def transmitMatrix(filtertype, alpha, M, K, oversampling_factor=1):
    # replaces old definition.
    taps = gfdm_filter_taps(filtertype, alpha, M, K, oversampling_factor)
    return gfdm_modulation_matrix(taps, M, K, oversampling_factor, False)
Exemple #15
0
def transmitMatrix(filtertype, alpha, M, K, oversampling_factor=1):
    # replaces old definition.
    taps = gfdm_filter_taps(filtertype, alpha, M, K, oversampling_factor)
    return gfdm_modulation_matrix(taps, M, K, oversampling_factor, False)
Exemple #16
0
def transmitMatrix(filtertype, alpha, M, K, N):
    # replaces old definition.
    taps = gfdm_filter_taps(filtertype, alpha, M, K, N)
    return gfdm_modulation_matrix(taps, M, K, N, False)