Efficient method for getting positive half axis only from FFT

27 views (last 30 days)
So, I understand how FFT works in Matlab fairly well (or so I like to think). However, I would like to be able to do something like the following:
load(x) % time domain signal data
fs = 5e9; % sampling frequency
Nfft = 10e4; % This is to get a 50 kHz frequency resolution in the bin sizes.
df = fs/Nfft;
tempY = fft(x); % phase data doesn't matter
Y = tempY(2:(600e6/df)+1); % Extract only the first 600 MHz of the FFT omitting DC-point.
clear tempY;
The 600e6/df+1 comes out to the 12001 index. But what I would like to do is omit the temp variable entirely, or at least handle it in a more memory efficient manner. (trying to analyze 32 sets of 100 trials at a time while avoiding loops as much as possible.)
I can reduce the FFT bin size, but but for reasons outside of this post I'd prefer not to. (And even if I did, I'd like to have more efficient code in the first place since I only need the first 600 MHz of the positive half axis after the FFT.)
edit: forgot to include the clear tempY once it was done being used.
  1 Comment
Daniel Kellett
Daniel Kellett on 9 Nov 2016
For anyone viewing this for getting the whole positive half axis, the above temp variable method is probably the best. You can also use the following code with little impact on overall performance, that is perhaps a bit easier to read:
paren = @(x,varargin{:}) x(varargin{:});
paren(fft(x,Nfft), 1:Nfft/2+1);
You can find an excellent explanation for the anonymous function here .
If you want only a specific portion of the positive half axis like I did, downsampling will serve you best if your main concern is cutting back on memory usage. (In which case see best answer)

Sign in to comment.

Accepted Answer

Daniel kiracofe
Daniel kiracofe on 4 Nov 2016
If I understand your question, you are getting the answer you want, but you are trying improve the efficiency. If you only care about 0 - 600 MHz, then the easiest thing that I can see is to downsample (using resample() or decimate() ) down to a sampling frequency of 1.2 GHz (or thereabouts). Then your fft() will give you only the frequencies you care about. Or more specifically, it will give a two sided spectrum from -600 Mhz to +600 MHz. You'll still need a temp variable if you just want a one sided spectrum, but it will at least be a smaller temp variable.
  3 Comments
Daniel kiracofe
Daniel kiracofe on 4 Nov 2016
I don't think there is any way to only compute only part of the spectrum. If you were directly computing a discrete fourier transform, you could just compute the coefficients that you cared about. But the "fast" part of the "fast fourier transform" comes from the fact that it is a divide and conquer algorithm. e.g. if you want to compute an fft of a vector X of 8 elements, it does that by first computing an fft of the even elements X([2 4 6 8]) then computing an fft of the odd elements X([1 3 5 7]), and then combining the results. The final 8 element result vector contains parts of both sets of computations. So there is really no way to just compute half of it. To get any of it, you have to compute all of it.
Again, if you do a DFT directly, you can just do part of it. If you wanted 5 elements out of a 12000 element array, then it is probably quicker to just do the fourier sum directly. But if you want, say, 25% of the vector, it is quicker to just do the fft directly.
Daniel Kellett
Daniel Kellett on 7 Nov 2016
This was my suspicion. I know how the FFT is computed, but was not positive there was no way it could be further optimized.
Down-sampling seems to be the best solution in terms of memory efficiency (while retaining speed). Though I did find a neat way you can skip the creation of the temp variable using anonymous functions. (Or more appropriately, neatly write it out in one line, as it ultimately uses the same amount of memory, indicating an implicit temp variable.)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!