You are on page 1of 19

March 15th, 2010

The DFT and the DTFT

It's finally time to start looking at the relationship between the discrete Fourier transform
(DFT) and the discrete-time Fourier transform (DTFT). Let's look at a simple rectangular
pulse, for . The DTFT of is:

Let's plot for over a couple of periods:

M = 8;
w = linspace(-2*pi, 2*pi, 800);
X_dtft = (sin(w*M/2) ./ sin(w/2)) .* exp(-1j * w * (M-1) / 2);
plot(w, abs(X_dtft))
title('|X(\omega)|')
It turns out that, under certain conditions, the DFT is just equally-spaced samples of the
DTFT. Suppose is the P-point DFT of . If is nonzero only over the finite
domain , then equals at equally spaced intervals of :

The MATLAB function fft computes the DFT. Here's the 8-point DFT of our 8-point
rectangular pulse:

x = ones(1, M);
X = fft(x)

X =

8 0 0 0 0 0 0 0

One 8 and a bunch of zeros?? That doesn't seem anything like the DTFT plot above. But
when you superimpose the output of fft in the right places on the DTFT plot, it all
becomes clear.

P = 8;
w_k = (0:P-1) * (2*pi/P);
X = fft(x);
plot(w, abs(X_dtft))
hold on
plot(w_k, abs(X), 'o')
hold off
Now you can see that the seven zeros in the output of fft correspond to the seven places
(in each period) where the DTFT equals zero.

You can get more samples of the DTFT simply by increasing P. One way to do that is to
zero-pad.

x16 = [x, zeros(1, 8)]

x16 =

Columns 1 through 15

1 1 1 1 1 1 1 1 0 0 0 0
0 0 0

Column 16

P = 16;
X16 = fft(x16);
w_k = (0:P-1) * (2*pi/P);
X = fft(x);
plot(w, abs(X_dtft))
hold on
plot(w_k, abs(X16), 'o')
hold off

Another way to increase P is to use the fft(x,P) syntax of the fft function. This syntax
computes the P-point DFT of x by using zero-padding. Let's try a 50-point DFT.

P = 50;
Xp = fft(x, P);
w_k = (0:P-1) * (2*pi/P);
X = fft(x);
plot(w, abs(X_dtft))
hold on
plot(w_k, abs(Xp), 'o')
hold off
If you've ever wondered what that whole zero-padding business was all about with Fourier
transforms, now you know. When you tack on a bunch of zeros to a sequence and then
compute the DFT, you're just getting more and more samples of the DTFT of the original
sequence.

I think the next logical place to go in our Fourier exploration is to start considering some of
the reasons why many people find the output of fft so surprising or puzzling. Here's a
sample:

Why isn't the zero frequency (or "DC" frequency) in the center of the output from
fft?
Why isn't the output of fft real when the input is symmetric?

Do you have puzzles to add? Let me know by adding your comments.

Get the MATLAB code


Published with MATLAB 7.9
By Steve Eddins

17:59 UTC | Posted in Fourier transforms | Permalink | 8 Comments

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently
closed.

8 Responses to The DFT and the DTFT

1. OysterEngineer replied on March 17th, 2010 at 14:33 UTC :

I am enjoying this series of blogs & encourage you to continue. This latest entry
was very helpful. I suspect that most users who use the fft function are really after a
dft with good calculation performance & really dont care how much of Cooley &
Tukeys genius is incorporated in the routine.

I think most users are happy to trust that World Class experts in signal processing
have ensured that these functions in MatLab do the right thing & perform
efficiently.

However, for folks like me who dont have a graduate exposure to signal
processing, Im interested in an fft type function because I want some frequency
domain insight into some real, time domain data. As such, the single detail that
always trips me up is how to relate the output of the fft function to a vector of real
frequencies that are meaningful to me. Im not talking about the difference between
Hertz & radians per second. Im talking about how the frequencies are non-
dimensionalized in the world of signal processing.

Both the FRP for fft & this blog entry are good examples of this issue. No where in
this blog do you mention units at all. Your frequency vector w spans / + 2pi, so
most of us would assume it is radians per second. But, this isnt specified and you
dont label the X axis of your plots. So, we are left guessing.

Lay users like me are further tripped up by this concept of negative frequencies. The
FRP for fft is just as bad in that it only addresses the frequency issue by inference in
the single example wherein they use the common shorthand of taking advantage of
the complex-conjugate nature of the fft output, throw away last half of the fft output
and generate a vector of only positive frequencies.

Certainly an fft function is more general & powerful than just for understanding
frequency domain characteristics of time domain data, so it is appropriate for
MatLab to provide this generality. However, since many, if not most, uses are for
understanding time domain data, the FRP should address this frequency detail
specifically.

Further, the FRP should include several more examples including ones that
specifically demonstrate the effect of real vs complex input data.
2. Amit replied on March 17th, 2010 at 15:00 UTC :

I am implementing a code from a paper (


http://www.cns.nyu.edu/~zwang/files/papers/icip00.pdf ) and i am having trouble
with the fft which is giving me very high values

[Long code fragment edited out. -SE]

The high value output from the fft is carried forward till my end result.

3. Steve replied on March 18th, 2010 at 12:05 UTC :

OysterEngineerExcellent questions and comments. I will follow up in additional


blog posts.

4. Steve replied on March 18th, 2010 at 12:08 UTC :

AmitIm afraid I cant help you with debugging your implementation of


something you read in a research paper, but I can suggest that you go back and
check all your assumptions. The MATLAB fft function computes the discrete
Fourier transform (DFT). Sometimes different people use different formulas for the
DFT. Most often the difference is in the scale factors used.

5. Amit replied on March 18th, 2010 at 14:55 UTC :

Thanks Steve ,ill try reading more on fft and using different scale factors

6. Fen replied on March 18th, 2010 at 18:49 UTC :

Hi Steve,

Thanks for this excellent series of blogs on the FT. I feel its one of those topics that
cannot be revisited enough. I use the DFT in matlab a lot for image processing tasks
but I can still manage to get confused about some of the concepts involved every so
often.

I have a question so far- you mention here that zero-padding is effectively for
increasing the sampling of the FT but isnt it also for preventing wraparound error
when filtering too?

Theres also Gibbs phenomenon/ringing and widowwing to consider I hope you


can cover these too in the future.

This is a great resource your making. Im looking forward to the rest.

Thanks,
Fen

7. Steve replied on March 18th, 2010 at 19:53 UTC :

FenI appreciate the encouragement, thanks. You are right that there is a different
way to think about zero-padding when you are doing frequency-domain based
filtering. I imagine Ill get to that, but Im not sure when. I touched briefly on
windowing back in December, and Ill come back to that topic again. I havent
really thought much yet about how to talk about Gibbs phenomenon. Thanks for
taking the time to make good suggestions.

8. Steve replied on March 19th, 2010 at 01:01 UTC :

FenI think I misunderstood your comment about avoiding wrap-around error.


Yes, when using the DFT to compute convolution, the inputs must be zero-padded
by the proper amount. The reason is related to the condition I gave in this post on P.
P must be at least as big as the nonzero domain of the output of the convolution,
which is N+K-1 for convolution of an N-point sequence with a K-point sequence.
Therefore the inputs must be zero-padded to at least N+K-1.

June 25th, 2010

Plotting the DTFT using the output of fft

In my Fourier transform series I've been trying to address some of the common points of
confusion surrounding this topic. For today's espisode I want to look at how to use the fft
function to produce discrete-time Fourier transform (DTFT) magnitude plots in the form
you might see in a textbook. Recall that the fft computes the discrete Fourier transform
(DFT). I described the relationship between the DFT and the DTFT in my March 15 post.

For my example I'll work with a sequence that equals 1 for and equals 0
elsewhere.
Here's a plot of the DTFT magnitude of this sequence:

Now let's see what get using fft.

x = ones(1, 5)

x =

1 1 1 1 1

X = fft(x);
plot(abs(X))
Wow, that's not anywhere close to the DTFT magnitude plot above. And why does it look
like it's only got two points? Well, take a look at the actual values of X:

X =

5 0 0 0 0

We have a 5 and four 0s. What's going on? I explained this back in my March 15 post when
I discussed the relationship between the DFT and the DTFT. The outputs of the DFT are
samples of the DTFT, and in this case the sample locations just happen to align with the
locations of four zeros in the DTFT.

You can get a finer sampling (and a much nicer-looking DTFT plot) by zero-padding. Here
I'll use the zero-padding syntax of fft.

N = 256;
X = fft(x, N);
plot(abs(X))
That's a smoother-looking curve, but it still looks quite a bit different than the DTFT
magnitude plot above. To explain the MATLAB output we're looking at, let me show a
DTFT magnitude plot that shows three periods instead of just one.
You can see that the output from MATLAB is one period of the DTFT, but it's not the
period normally plotted, which is from to . Instead, it's the period from 0 to . To get a
plot from to , use the fftshift function.

plot(abs(fftshift(X)))
That leaves us with the question of labeling the frequency axis. We want a plot in radians
from to .

The way I always remember the frequency scaling between the DFT and the DTFT is this:
the length of the DFT corresponds to the frequency in the DTFT.

So the frequencies in radians corresponding to the output elements of fft are:

w = 2*pi * (0:(N-1)) / N;

But we're calling fftshift to plot the magnitude of the DTFT, so we have to perform a
similar shift on our frequencies:

w2 = fftshift(w);
plot(w2)
Now our frequencies start at and have a discontinuity in the middle. Here's one way to
fix that up:

w3 = unwrap(w2 - 2*pi);
plot(w3)
Now we can redo our magnitude DTFT plot with the x-axis labels.

plot(w3, abs(fftshift(X)))
xlabel('radians')
Often I like to see the multiples of more clearly along the x-axis. One way to accomplish
this is to normalize the frequency variable by .

plot(w3/pi, abs(fftshift(X)))
xlabel('radians / \pi')
Another option is to try Alan's pilabels contribution on the MATLAB Central File
Exchange.

For the next time, I'm thinking of tackling the question of why the following output is
complex:

fft([1 2 3 2 1])

ans =

9.0000 -2.1180 - 1.5388i 0.1180 + 0.3633i 0.1180 -


0.3633i -2.1180 + 1.5388i

Many people expect it to be real.

Get the MATLAB code


Published with MATLAB 7.10
By Steve Eddins

18:51 UTC | Posted in Fourier transforms | Permalink | 6 Comments

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently
closed.

6 Responses to Plotting the DTFT using the output of fft

1. OysterEngineer replied on June 29th, 2010 at 09:08 UTC :

Steve,

Thanks for another well written column.

2. SanguineCat replied on July 7th, 2010 at 23:46 UTC :

I went through the Fourier articles yesterday, and theyre very helpful. Thanks
Steve.

The following question may be due to my inability to understand the unwrap


function correctly. Does anyone know why the unwrapping the following code does
not produce a linear result?

Fs = 20;
N=100;
F=[0:N-1]/N*Fs;
plot(unwrap(fftshift(F)-Fs))

3. Steve replied on July 12th, 2010 at 14:57 UTC :

SanguineCatThe function unwrap is meant for correcting discontinuities of phase


angles caused by a branch cut in the complex plane. It is looking for discontinuities
of greater than pi, and your example doesnt have any discontinuities that big. You
could try reducing the jump tolerance, which is the optional second input
argument to unwrap.

4. Steve replied on July 12th, 2010 at 15:34 UTC :

SanguineCatOops, I didnt explain that quite right. The function unwrap fixes
discontinuities by adding multiples of 2*pi. The thing you are trying to unwrap isnt
made up of phase angles and the discontinuity isnt close to a multiple of 2*pi, so
unwrap is the wrong thing to use.

5. Ding replied on August 29th, 2010 at 18:02 UTC :

Nice Post, Steve. I learned something from the use of unwrap function here.

Regarding to labeling the frequency axis of FFT spectrum output, there might be a
much easy way like this:

w4=2*pi*(-N/2:N/2-1)/N;
figure
plot(w4/pi,abs(fftshift(x)));
xlabel(radians / \pi);

Normally, N is chosen even in FFT zero padding

6. Starstrike replied on September 2nd, 2010 at 10:06 UTC :

My first introduction to the unwrap function its one I use so often Id created a
subfunction of my own to do it, without discovering unwrap. I can at least console
myself that my custom version is faster but I rarely call it multiple times, so might
just switch to the greater redundancy of unwrap.

Interesting to see that you can get the DTFT from the DFT; oddly using DFTs all
the time I was looking for a fast way to calculate the DTFT recently.

Dings code, as implied, would need a separate definition of w4 in the case of odd
N, eg for unpadded DFTs.

You might also like