What is the use case for ifft's trailing zero padding? Why is that the default?

Hi all, I'm trying to figure out what the use case is for ifft(Y,n) According to the documentation: X = ifft(Y,n) returns the n-point inverse Fourier transform of Y by padding Y with trailing zeros to length n.
These trailing zeros give incorrect results for every case I've seen. Is there something I'm not understanding? Shouldn't they put the padding zeros in the center: after npoints/2? This seems to be a common default as well. I've noticed python fft codes do this too. This is particularly relevant to me because I want to solve a differential equation spectrally using a limited number of modes, but then plot the solutions in real space with high fidelity.
Example Code Demonstrating For simplicity's sake: if I have 10 original data points of a periodic signal, but I want to replot it with 20 points, I should be able to use this code to do so. Instead, I get complex solutions. nsamples = 10; xs = linspace(0,2*pi*(1-1/nsamples) ,nsamples);
ys = sin(xs); ydefault = ifft(fft(ys),20);
disp(ys) disp(ydefault)

 Accepted Answer

Hi Kevin,
I think the title question is misleading. The result of zero padding ifft is not incorrect. It does exactly what it claims to do. Nothing more, nothing less.Even if it's not what's desired for a specific problem, it's not incorrect.
The real question is in the text of the question, specifically: "what the use case is for ifft(Y,n)"
One possbility is that different fields of study use different conventions for the sign of the exponent in the transform. So if my field of study defines the DFT with a positive exponent, I can use ifft() to compute my DFT, in which case zero padding in ifft does exactly what I want (interpolate in the frequency domain).
To be sure, zero padding in the middle of the ifft array can be useful as well to interpolate in the time domain, but that's a different problem. And if zero padding in the middle is desired, we can alwasy do fftshift -> zero pad the ends -> ifftshift.

5 Comments

Thank you Paul. I edited the title to be more clear. I appreciate you taking your time to answer. That makes a lot of sense. Although I wish the documentation was a bit more clear on properly padding for interpolation.
The other part of the qeustion is "why is that the default?" I suspect, but don't know for sure, that the more general reason is that it is important that the zero padding as implemented maintain certain important properties between fft and ifft. For example:
rng(100);
y = rand(1,5) + 1j*rand(1,5);
Y1 = ifft(y,10);
Y2 = conj(fft(conj(y),10))/10; % compute the ifft using only fft
Y1 - Y2
ans = 1×10
0 0 0 0 0 0 0 0 0 0
This example suggests also that there could be commonality in the underlying code that implements both functions, in which case fft and ifft would have to treat zero padding the same way. But that's just speculation on my part.
An important reason not to have zeropadding at the start of an array is that both the fft and the ifft are set up so that both their input and output expect the first point in the corresponding time array to be t = 0, and the first point in the corresponding frequency array be f = 0. A hard and fast convention like that seems to be a good idea. Zeropadding at the end, or even in the middle, has an effect but does not mess with that convention. Zeropadding at the beginning obviously would. It's certainly possible to zeropad at the beginning anyway, but keeping track of what is going on will be a chore.
<modified per Paul's comment below> [
[ The fftshift and ifftshift functions do shift the zero of the corresponding arrays up to the center or down to the first element respectively, and it is up to the user to keep track of the right number of shifts so that fft and ifft still work correctly. ]
Hi David,
Maybe I'm misreading the statement in [], but I thought that typically (not always) fftshift operates on the frequency array and ifftshift operates on the time array, and that ifftshift shifts the zero of the input array from the center array to the start of the array, i.e., it "undoes" the result of fftshift.
HI Paul,
Thanks for the observation and correction. For odd n that's the way it has to be, ifftshift undoes fftshift and those functions are distinct. I mistakenly had only even n in mind, for which the array halves are swapped, both fftshift and ifftshift do the same thing, each is its own inverse, and each simultaneously takes 0 up to the 'center' (n/2+1) should it be the first element, and takes 0 down to the first element should it be at the 'center'.

Sign in to comment.

More Answers (1)

Hi Kevin.
Zeropaddinig has consequences. It also has its uses, but sometimes the results are unexpected.
First of all, whatever ys is, ifft(fft(ys)) comes out the same as ys (not counting tiny numerical error). Zeropadding any signal is going to change the result. In your case the initial ys is a periodic function in the xs window as it should be. For that sine wave, the fft of ys is nonzero at two frequency points. One is at pos. frequency +1. The other is at neg. frequency -1, which for a 10 point fft is the same as pos. frequency +9 (the freq array runs from 0 to 9).
Padding the frequency array changes the positions of the frequency peaks in such a way that you end up with one real sine wave and one imaginary cosine wave, as you can see with
plot(1:20,real(ydefault),'-o',1:20,imag(ydefault),'o-')
Each of those waves are every-other-point samples in a new 20 point x array.
All of this is totally independent of whether you later choose to cut the frequency response down by a factor of 2 to look at, say, positive frequencies only.

Products

Release

R2022a

Asked:

on 19 Jul 2022

Edited:

on 4 Aug 2022

Community Treasure Hunt

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

Start Hunting!