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)  

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.

  • $\begingroup$ Your new question isn't really clear. If you have a new question, you should start a new thread. As the accepted answer indicates, you can apply the shift you're looking for in either the time or frequency domain. $\endgroup$
    – Jason R
    Oct 16, 2012 at 15:15
  • $\begingroup$ Actually I have not been able to make it work exactly as i wanted - hence my own solution came up. The frequency domain shift is pretty neat, however it is pretty difficult to verify since the time domain looks as when there is no shift present due to some issue with the oversampling/missing hereof I guess. So, no extra question, I figured a way to do it without using either the frequency domain or time domain solution per say. Just good old math. $\endgroup$
    – Hoejrup
    Oct 16, 2012 at 16:01

2 Answers 2


For implementing the frequency shift of 7.5 kHz you will have to apply oversampling at some point in your system. There are two principal methods to achieve this: in frequency domain or in time domain.

Frequency domain

You could simply apply an additional zero padding in frequency domain by using a 2048 IFFT and by setting every second subcarrier to zero. You then shift all subcarriers by one frequency bin to achieve the frequency shift. This will maintain the frequency spacing of 15 kHz but the bandwidth of each subcarrier will be divided by two compared to the 1024 IFFT.

Time domain

You apply two-times oversampling to the time domain signal at the output of the IFFT. This can be done by padding a zero sample after each sample followed by a lowpass filter or some other interpolation method. The frequency shift can then be achieved by multiplying the resulting signal by $\exp(j\Omega_1 n)$, where $\Omega_1$ is the 7.5 kHz normalized to the new sampling frequency (double the original sampling frequency) and $n$ is the discrete time.

Which method to choose depends on how close your simulation should be to the hardware implemenation. If the system you model has some intermediate frequency oscillator to do the frequency shift, the time domain method can model this. But if your digital-to-analog converter is fast enough and if you can implement a 2048-IFFT at the required speed, this is probably the way to go and you should therefore model it accordingly.

  • $\begingroup$ I think I have figured out the problem now. Will update my main post. Did a mix of both things, and some math. It seems that when you apply oversampling in the frequency domain you get a replica of the signal in the time domain. And cutting away the replica leaves me in the same state as before. $\endgroup$
    – Hoejrup
    Oct 16, 2012 at 14:37
  • $\begingroup$ Thanks for your answer Mr.Deve But could you please explain for me why we need to apply two-times oversampling? Thanks you! $\endgroup$
    – T. Link
    Jan 9, 2017 at 4:55

Use time-domain modulation to shift the frequency before the FFT: Multiply the time domain signal with a complex sinusoid having a period of 2x the FFT frame duration.

This will shift the signal cyclically in the frequency domain by 1/2 of the FFT spacing. Carriers on the far edges of the spectrum may be corrupted, but in LTE those are padding carriers.

This probably takes a lot less computation than oversampling and using a bigger FFT.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.