First post here, trying to make it as good as possible. Do not know how to make the Python code look nice - any tips? :) Anywho - to the main problem:
I am currently working on simulating the uplink of LTE starting with the SC-FDM(A) modulator. Now, the "first edition" is the OFDM modulator implemented in Python and basically:
import numpy as np
import numpy.fft as npf
numSymbols = 12*10 # 10 resource blocks, each containing 12 subcarriers. FFTsize = 1024
tmp1 = np.array(np.random.randint(0,2,numSymbols))*2-1 tmp2 = np.array(np.random.randint(0,2,numSymbols))*2-1
inputSymbols = (np.array(tmp1) + 1j*np.array(tmp2))/np.sqrt(2) # QPSK modulation
TxSamples = npf.ifft(inputSymbols,FFTsize) # Zero-padded IFFT.
TxSamples is the OFDM modulated signal of some random binary input. The subcarrier mapping is implicit in the IFFT due to the zero-padding.
My issue is the fact that LTE Uplink uses half a subcarrier shift in relation to DC. My implementation is build upon the assumption that each entry in the IFFT is spaced with 15kHz (the required subcarrier spacing according to LTE) and this is also the case for two other implementations I have found here and here.
So, how can this half subcarrier shift (7.5kHz) be incoorperated into the simulation?
Let me know if you need more information - do not really know what is to much or to little information regarding my issue.
Thanks in advance.
** UPDATE: **
So, I tried to do the frequency oversampling by simply adding a zero in between samples. This resulted in me having a replica in the time domain. Cutting away this replica got me back to the starting point.
What I have done in order to solve the problem is basically mathematical driven. From the formula for the DFT it is possible to derive that you can simply multiply the input symbols by a complex exponential. This will shift the frequency. The Python code is basically (overwriting the last line in the example above):
ism = []
for m in range(len(inputSymbols)):
ism += [inputSymbols[m]*np.exp(1j*np.pi*m/FFTsize)]
TxSamples = npf.ifft(ism,FFTsize)
which yields the correct time domain representation, with no sorta explicit oversampling. To verify scipy can be used as:
import scipy.signal as sps
import pylab as pl
ts1 = sps.resample(TxSamples,len(TxSamples)*2)
pl.figure(1)
pl.plot(10*np.log10(abs(npf.fft(ts1))))
which should show that the signal has now been oversampled by two and that the frequency bins are located correctly, while the time domain representation is not broken.
I suppose this way one makes sure that both domains are "the same". Since by simply oversampling in the frequency domain it is not possible to represent the time domain signal correctly. I do not know - it seems that this "hacked" solution works. However kind corrections are always welcome.