Beispiel #1
0
def gfdm_filter_taps(filtertype, alpha, M, K, oversampling_factor=1.):
    N = oversampling_factor
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K * N, alpha, 1. * K * N, 1.)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K * N, alpha, 1. * K * N, 1. )
    return h
Beispiel #2
0
def gfdm_filter_taps(filtertype, alpha, M, K, oversampling_factor=1.):
    N = oversampling_factor
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K * N, alpha, 1. * K * N, 1.)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K * N, alpha, 1. * K * N, 1.)
    return h
Beispiel #3
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
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K, alpha, K, 1)
    h = np.roll(h, h.shape[-1] / 2)
    H = np.fft.fft(h)
    H_sparse = np.concatenate((H[0:(M * L) / 2], H[-(M * L) / 2:]))
    # 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) * x_t
    return x_t
Beispiel #4
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
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M*K, alpha, K, 1)
    h = np.roll(h, h.shape[-1]/2)
    H = np.fft.fft(h)
    H_sparse = np.concatenate((H[0:(M*L)/2], H[-(M*L)/2:]))
    # 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)*x_t
    return x_t
Beispiel #5
0
def gfdm_tx_fft(x, filtertype, alpha, M, K):
    '''
        Realization of GFDM-Transmitter in FFT:
            Required input: x a np.array of length M*K
            FFT is applied in shifted version (zero-frequency term is centered)
            First symbol is on -freq_max and last symbol ist on freq_max
            h: Prototype-filter impulse response
            s_e[n]:[s_0[n] 0{M-1} s_1[n] .... s_N-1[n] 0{M-1}]
            x[n] = h (*) (IFFT(s_e[n]))
            x_gfdm = sum_M(circshift(x[n],nN))
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M*K, alpha, K, 1)
    # Initialization of output vector
    x_out = np.zeros(M*K, dtype='complex')
    # circulary move filter window to symbol 0
    h = np.roll(h, -(M*K/2))
    # for each gfdm-block
        # for each timeslot
    for m in xrange(M):
        # select the K next symbols
        #symbols = np.fft.ifftshift(x[(m*K):(m+1)*K])
        symbols = np.fft.ifftshift(np.array([x[k*M+m] for k in xrange(K)]))
        # transform K symbols to K carriertones in time-domain
        sym_t = np.fft.ifft(symbols)
        sym_te = np.array([])
        # Repeat result M-times in a vector
        for m2 in xrange(M):
            sym_te = np.concatenate((sym_te, sym_t))
        # multipy with transmit filter -> better convolve?
        sym_te = np.convolve(sym_te, h, mode='same')
        #sym_te = np.multiply(sym_te,h)
        # shift result m*K samples to the right and add it up to the result
        # vector
        x_out = np.add(x_out, np.roll(sym_te, m*K))

    return x_out
Beispiel #6
0
def gfdm_tx_fft(x, filtertype, alpha, M, K):
    '''
        Realization of GFDM-Transmitter in FFT:
            Required input: x a np.array of length M*K
            FFT is applied in shifted version (zero-frequency term is centered)
            First symbol is on -freq_max and last symbol ist on freq_max
            h: Prototype-filter impulse response
            s_e[n]:[s_0[n] 0{M-1} s_1[n] .... s_N-1[n] 0{M-1}]
            x[n] = h (*) (IFFT(s_e[n]))
            x_gfdm = sum_M(circshift(x[n],nN))
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K, alpha, K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K, alpha, K, 1)
    # Initialization of output vector
    x_out = np.zeros(M * K, dtype='complex')
    # circulary move filter window to symbol 0
    h = np.roll(h, -(M * K / 2))
    # for each gfdm-block
    # for each timeslot
    for m in xrange(M):
        # select the K next symbols
        #symbols = np.fft.ifftshift(x[(m*K):(m+1)*K])
        symbols = np.fft.ifftshift(np.array([x[k * M + m] for k in xrange(K)]))
        # transform K symbols to K carriertones in time-domain
        sym_t = np.fft.ifft(symbols)
        sym_te = np.array([])
        # Repeat result M-times in a vector
        for m2 in xrange(M):
            sym_te = np.concatenate((sym_te, sym_t))
        # multipy with transmit filter -> better convolve?
        sym_te = np.convolve(sym_te, h, mode='same')
        #sym_te = np.multiply(sym_te,h)
        # shift result m*K samples to the right and add it up to the result
        # vector
        x_out = np.add(x_out, np.roll(sym_te, m * K))

    return x_out
Beispiel #7
0
def transmitMatrix(filtertype, alpha, M, K, N):
    '''
        Create Convolution Matrix for pulse shaping

        filtertype : (rrc,rc)
        alpha : roll-off-factor
        sampling_rate : sampling rate (in Hz)
        symbol_period : symbol period (in s)
        M : number of symbol time slots
        K : number of subcarriers

        h_matrix: array of impulse responses for time slot (0...M-1)
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M * K * N, alpha, N * K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M * K * N, alpha, N * K, 1)
    # Move filter cyclic
    G_tx = np.array(
        [np.roll(h, m - (M * K * N / 2)) for m in xrange(M * K * N)])
    S_mn = samplingMatrix(M, K * N)
    S_nm = samplingMatrix(K, M)
    if N > 1:
        # if oversampling is specified add zeros to samplingMatrix
        S_nm = np.insert(S_nm,
                         M * K / 2,
                         np.zeros((M * K * (N - 1), K), dtype='complex'),
                         axis=0)
    W_H = fourierMatrix(M * K * N).conj().transpose()
    # Resample Filter
    G_tx_s = np.dot(G_tx, S_mn)
    # Resample FourierMatrix
    W_s = np.dot(S_nm.transpose(), W_H)
    # compute and use all elements of the main diagonal W_s.dot(G_tx_s)
    A = np.array([(np.kron(W_s.transpose()[n], G_tx_s[n]))
                  for n in xrange(K * M * N)])

    return A
Beispiel #8
0
def transmitMatrix(filtertype, alpha, M, K, N):
    '''
        Create Convolution Matrix for pulse shaping

        filtertype : (rrc,rc)
        alpha : roll-off-factor
        sampling_rate : sampling rate (in Hz)
        symbol_period : symbol period (in s)
        M : number of symbol time slots
        K : number of subcarriers

        h_matrix: array of impulse responses for time slot (0...M-1)
    '''
    if filtertype == "rrc":
        time_h, h = cp.rrcosfilter(M*K*N, alpha, N*K, 1)
    elif filtertype == "rc":
        time_h, h = cp.rcosfilter(M*K*N, alpha, N*K, 1)
    # Move filter cyclic
    G_tx = np.array([np.roll(h, m - (M*K*N/2)) for m in xrange(M*K*N)])
    S_mn = samplingMatrix(M, K*N)
    S_nm = samplingMatrix(K, M)
    if N > 1:
        # if oversampling is specified add zeros to samplingMatrix
        S_nm = np.insert(
            S_nm, M * K / 2, np.zeros((M * K * (N - 1), K), dtype='complex'),
            axis=0)
    W_H = fourierMatrix(M*K*N).conj().transpose()
    # Resample Filter
    G_tx_s = np.dot(G_tx, S_mn)
    # Resample FourierMatrix
    W_s = np.dot(S_nm.transpose(), W_H)
    # compute and use all elements of the main diagonal W_s.dot(G_tx_s)
    A = np.array([(np.kron(W_s.transpose()[n], G_tx_s[n]))
                 for n in xrange(K*M*N)])

    return A