0% found this document useful (0 votes)
121 views9 pages

Lyons FFT Interpolation Based On FFT Samples PDF

Uploaded by

jarrero
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
121 views9 pages

Lyons FFT Interpolation Based On FFT Samples PDF

Uploaded by

jarrero
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

FFT Interpolation Based on FFT Samples: A

Detective Story With a Surprise Ending


By Richard Lyons [April, 2018-Version-2]
This blog presents several interesting things I recently learned regarding
the estimation of a spectral value located at a frequency lying between
previously computed FFT spectral samples. My curiosity about this FFT
interpolation process was triggered by reading a spectrum analysis paper
written by three astronomers [1].

My fixation on one equation in that paper led to the creation of this blog.

Background
The notion of FFT interpolation is straightforward to describe. That is, for
example, given an N = 16 sample x(n) time-domain sequence shown in Figure
1(a), performing an N = 16 point FFT on x(n) produces the |X(m)| magnitude of
samples shown by the red dots in Figure 1(b). The blue dashed curve in Figure
1(b) is the magnitude of the discrete-time Fourier transform (DTFT) of x(n),
what I like to call the "true spectrum" of x(n).

x(n) input time sequence (N = 16)


1

0.5

0
(a) 0 5 10 15
n

True spectral magnitude


(|DTFT|) of x(n)
5
Red dots are the |X(m)| FFT
|X(m)|

magnitude samples

0
0 3 4 5 10 15
Freq (m)
(b) |X(k)| where
k = 4.4688

Figure 1: (a) An x(n) time sequence; (b) the spectral


magnitude of x(n).

The process of FFT interpolation is estimating an X(k) spectral value at, for
example, a non-integer frequency of k = 4.4688 lying between the m = 4 and
m = 5 FFT samples. The magnitude of X(k) is marked by the bold 'x' in Figure
1(b).

An X(k)Estimation Equation That Does Not Work


Reference [1] presents the following equation for computing a single X(k)
spectral value based on N FFT samples:

Copyright © Richard Lyons 2018 1


N 1
sin[(k-m)]
X(k)   X(m)  ej(k  m) (1)
(k-m)
m 0

where:

N = the number of input x(n) samples and number of FFT samples


X(m) = the original FFT samples (the FFT of x(n))
m = the freq-domain integer index of the X(m) samples where 0 ≤ m ≤ N-1
k = the "FFT bin-like" frequency value of our desired spectral
value where 0 ≤ k ≤ N-1, and k is not an integer
j = sqrt(-1).

To avoid overwhelming the reader with too many algebra equations, I've
included the derivation of Eq. (1) in Appendix.

Not having seen Eq. (1) before I decided to model it using MATLAB software.
Plugging my Figure 1(b) complex-valued X(m) FFT samples and k = 4.4688 into
Eq. (1) I computed an XRef.[1](4.4688) value of:

XRef.[1](4.4688) = -1.1023 -j1.1053.

Next, padding the x(n) time sequence with lots of zero-valued samples I
computed a finer-granularity spectrum shown by the blue dashed curve in
Figure 1(b). From that finer-resolution spectrum I learned the true value of
XTrue(4.4688) is:

XTrue(4.4688) = 0.3537 -j1.0489

which is not even close to the above XRef.[1](4.4688) spectral value computed
using Eq. (1)! So what's going on here(!)?

Knowing that my home-grown MATLAB code is about as reliable as the paper


towel dispenser in the Men's Room, I sked our DSP colleague Neil Robertson to
implement Eq. (1) using my above x(n) sequence and a value of k = 4.4688.
Neil graciously agreed and his MATLAB code produced the same incorrect
XRef.[1](4.4688) = -1.1023 -j1.1053 that I obtained.

So now it seems likely that Eq. (1) is not valid. But if that is true, how
could the three authors of Reference [1] have missed that error? That was the
mystery I set out to solve.

We'll revisit Eq. (1) later in this blog and learn something interesting in
our quest to understand that equation.

An X(k) Estimation Equation That Does Work


Knowing that Eq. (1) is questionable I started looking through my DSP books
to find a valid FFT interpolation formula. In an old out-of-print book
written by two DSP pioneers [2], I found the following expression for
computing the spectral value at non-integer frequency k based on N X(m) FFT
samples:

N 1 X(m) ej(2k/N )[(N -1)/2] sin(k)


X(k)   N  jm/N . (2)
m 0 e sin[ (k- m)/N )
]

Copyright © Richard Lyons 2018 2


Equation (2) produces correct FFT interpolation results and its derivation is
given in Appendix B. Using [2]'s z-transform derivation approach I performed
a modified derivation to obtain the following computationally simpler FFT
interpolation equation that also works just fine:

N 1 X(m) 1  ej2k
X(k)   N  . (3)
m 0 1  ej2(k  m)/N

My derivation of Eq. (3) is presented in Appendix C.

Quiz of the Day


Equation (3) is a correct way to compute an interpolated X(k) value, but look
at it carefully. Before continuing, do you see a way to reduce the number of
arithmetic operations needed to compute a single X(k) value? Did you notice
that neither the numerator nor the 1/N factor inside the summation in Eq. (3)
are functions of m? That fact allows us to move them both outside the
summation giving us:

1  ej2k N  1 X(m)
X(k)    . (4)
N j2(k  m)/N
m 0 1  e

Equation (4) has a significantly reduced computational workload relative to


that of Eq. (3) as we shall see. Don't feel bad if you didn't foresee those
beneficial simplifications leading to Eq. (4). Neither did I—while writing
this blog I found those slick algebraic moves in [3].

So now, Eq. (4) is my preferred method for computing a single interpolated


X(k) spectral value based on N FFT samples. Now that we have a workable Eq.
(4), let's briefly revisit the suspicious Eq. (1).

Here's What's Wrong With Eq. (1)


In Appendix A you'll see the published derivation of the troublesome Eq. (1).
One intermediate step in that derivation, my Eq. (A-5) repeated here as Eq.
(5), produces the following expression for our desired X(k) as:

N 1
1 sin[(k-m)]
X(k)    X(m)  ej(k  m)(1-1/N )  . (5)
N sin[(k-m)/ N]
m 0

Equation (5) works just fine for computing our desired X(k)! So now it's
interesting to see what went wrong in Eq. (1). The authors of [1] applied two
algebraic approximations to Eq. (5) to produce the faulty Eq. (1):

Approximation# 1:
Based on the assumption that N >> 1, they used the venerable
approximation 'sin(x) = x for small x' (employed in almost
every DSP textbook) to simplify the Eq. (5) ratio's
sin[(k-m)/N] denominator to (k-m)/N for Eq. (1). The problem
in doing this is factor (k-m) can be almost as large as N in
which case the angle (k-m)/N is not small making the
approximation invalid.

Approximation# 2:
In the exponent of Eq. (5) they replaced the factor

Copyright © Richard Lyons 2018 3


(1-1/N) with 1 to produce Eq. (1). The angular error induced
by this approximation, depending on k, can be as large
o
as /2 radians (90 !), regardless of the value of N.

Examples of the errors of those two approximations are shown in Figure 2.

Correct denominator Correct angle of


in Eq. (5) exponent in Eq. (5)

0 3

–1

Radians
2

–2 1

–3
0
0 20 40 60 0 20 40 60
m m
Incorrect denominator (b) Incorrect angle of
(a) in Eq. (1) exponent in Eq. (1)

Figure 2: Approximations' errors, versus m, when k = 2.4688


and N = 64:(a) Approximation# 1 error;
(b) Approximation# 2 error.

Analyzing the errors induced by those two approximations solves the mystery
of why Eq. (1) is flawed. By the way, I've modeled Eq. (1) for values of
N = 16 out to N = 16384 with no improvement in its accuracy for larger N.
Next we discuss the computational costs of this blog's FFT interpolation
equations.

Computational Workload Comparisons


It's enlightening to compare the necessary arithmetic operations needed to
implement the correct FFT interpolation equations given in this blog.

Assuming we have previously computed and stored all the constant factors in
our equations that are not functions of k or m, Table 1 shows the reduction
in the necessary computations needed by Eqs. (4) and (5) relative to Eqs. (2)
and (3). (In Table 1, a "Trigonometric Computation" means computing the sine
or cosine of some given angle.)

Table 1: Computational workloads of the above equations


computing a single X(k) value based on N FFT samples.
Equation: Real Real Real Trigonometric
Adds: Multiplies: Divides: Computations:

Eq. (2) 8N + 1 20N + 3 2N + 1 6N


{Ref. [2]}
Eq. (3) 10N 13N + 1 2N + 1 4N
{Lyons}
Eq. (4) 7N + 1 7N + 5 2N + 1 2N + 2
{Ref. [3]}
Eq. (5) 5N + 1 9N + 3 N + 2 4N

We remind the reader that Trigonometric Computations and Real Divides are far
more computationally costly than Real Adds and Real Multiplies.

Copyright © Richard Lyons 2018 4


Here's the "Surprise Ending" To This Blog
While struggling to create Table 1 it finally hit me! The fastest way to
compute a single interpolated FFT spectral sample at frequency k is to merely
compute a brute force N-point DFT of the original x(n) time samples using:

N 1
X(k)   x(n)  ej2(kn)/N (6)
n 0

where, again, 0 ≤ k ≤ N-1, and k is not an integer. Assuming the x(n) input
in Eq. (6) is real-only, the computational workload comparison of Eq. (6) to
my favorite Eq. (4) is given in Table 2.

Table 2: Computational workloads of Eqs. (4) and (6).


Equation: Real Real Real Trigonometric
Adds: Multiplies: Divides: computations:

Eq. (4) 7N + 1 7N + 5 2N + 1 2N + 2
{Ref. [3]}
Eq. (6) 2N 4N + 1 1* 2N
{DFT}
[* This single divide is the 1/N operation is used once to compute
and store the constant 2/N factor for the exponent of Eq. (6).

From Table 2 we see that Eq. (6) requires significantly fewer arithmetic
operations—notably eliminating 2N of those costly 'Real Divides'—than Eq.
(4).

Conclusions
I presented an X(k) FFT interpolation equation published in the literature,
Eq. (1), for computing a single X(k) spectral value based on N FFT samples,
where frequency k is not an integer. Equation (1) is not valid and I showed
why that is so. (I remain troubled by this and perhaps someone can prove me
wrong.) Next I presented four different expressions, Eq. (2) through Eq. (5),
for computing an X(m) sample and compared their computational costs. Finally
I realized the most efficient method for computing a single X(m) sample is to
simply perform an N-point DFT using Eq. (6).

I apologize for this blog being so lengthy. I didn't have the time to make it
shorter.

References
[1] S. Ransom, S. Eikenberry, and J. Middleditch, "Fourier Techniques For
Very Long Astrophysical Time-Series Analysis", The Astronomical Journal,
Sept. 2002, Section 4.1, pp. 1796.
[http://iopscience.iop.org/article/10.1086/342285/pdf]

[2] L. Rabiner and B. Gold, Theory and Application of Digital Signal


Processing, Prentice Hall, Upper Saddle River, New Jersey, 1975, p. 54.

[3] J. Proakis and D. Manolakis, Digital Signal Processing-Principles,


Algorithms, and Applications, 3rd Ed., Prentice Hall, Upper Saddle

Copyright © Richard Lyons 2018 5


River, New Jersey, 1996, pp. 408.

Appendix A: Derivation of Eq. (1)


This appendix shows the derivation of the above Eq. (1) originally presented
as Eq. (29) in [1]. (For hopefully easier readability I changed the variable
names from those in the original published derivation to those variables
given below.) We start by using the standard expression for an N-point
discrete Fourier transform (DFT) as:

N 1
X(k)   x(n)  ej2(kn)/N (A-1)
n 0

where x(n) is our input time-domain sequence, integer n is 0 ≤ n ≤ N-1, X(k)


is the complex-valued spectral value we wish to estimate, k (a non-integer
real number) is a DFT bin index-like frequency value in the range
0 ≤ k ≤ N-1, and ±j = sqrt(-1).

Because we have the X(m) sequence (the DFT of x(n)) available to us, we can
replace x(n) in Eq. (A-1) with the inverse DFT of X(m) as:

1 N 1
N 1  
X(k)   
N
 X(m)ej2(mn)/N   ej2(kn)/N

n 0  m 0 

N 1 N 1 N 1 N 1
ej2n(k-m)/N ej2[(k-m)/N]n .
1 1

N
 X(m)  
N
 X(m)  (A-2)
m 0 n 0 m 0 n 0

The second summation in Eq. (A-2) is a 'sum of a power series in n' and it
has a closed form. Using the summation–to-closed form identity:

N 1 sin(N /2)
 ejn  ej(N -1)/2  (A-3)
sin(/2)
n 0

we can write the second summation in Eq. (A-2) as:

N 1
sin[(k-m)]
 ej2[(k-m)/N]n  ej2[(k-m)(N -1)/(2N )] 
sin[(k-m)/N]
n 0
sin[(k-m)]
 ej[(k-m)
(1-1/N )  . (A-4)
sin[(k-m)/N]

Plugging Eq. (A-4) in for the second summation in Eq. (A-2) allows us to
rewrite Eq. (A-2), our desired A(k) expression, as:

N 1
sin[(k-m)]
X(m)  ej[(k-m)
1 (1-1/N) 
X(k) 
N
 sin[(k-m)/N]
(A-5)
m 0

In [1] the authors continue with the following two mathematical


simplifications:

sin() =  for small 

Copyright © Richard Lyons 2018 6


applied to the denominator in Eq. (A-5) and

(1-1/N) = 1 for large N,

applied to the exponent in Eq. (A-5) yielding [1]'s final expression for X(k)
as:

N 1
sin[(k-m)]
X(k)   X(m)  ej(k  m) (A-6)
(k-m)
m 0

which I presented as Eq. (1) in the first part of this blog.

Appendix B: Derivation of Eq. (2)


This appendix shows the derivation of this blog's Eq. (2) obtained from [2],
and provides the missing algebraic steps not included in [2]. We start by
using the standard expression for the z-transform of the x(n) input sequence
as:

N 1
X(z)   x(n)zn . (B-1)
n 0

Because we have the X(m) sequence (the DFT of x(n)) available to us, we can
replace x(n) in Eq. (B-1) with the inverse DFT of X(m) as:

N 1 n
1 N 1
N 1   N 1
X(m) ej2m/N z1 
X(z)   
N
 X(m)ej2(mn)/N   zn 
  N
  
(B-2)
n 0  m 0  m 0 n 0

The summation within the brackets in Eq. (B-2) is a 'sum of a power series in
n' and it has a closed form. Using the summation–to-closed form identity:

N 1 1-rN
 rn  (B-3)
1-r
n 0

j2m/N -1
where r = e z , we can write

 
N
N 1 1  ej2m/N z1
n 1  zN
 ej2m/N z1   j2m/N z1

j2m/N z1
. (B-4)
n 0 1  e 1  e

Plugging Eq. (B-4) in for the second summation in Eq. (B-2) allows us to
write our X(z) expression as:

N  1 X(m) 1  zN
X(z)   N  . (B-5)
m 0 1  ej2m/N z1

So here's where we stand; Eq. (B-5) tells us how to compute X(z), for any z,
using our X(m) DFT samples. Now all we have to do is evaluate Eq. (B-5) on
the z-plane's unit circle at a frequency of  radians, 0 ≤  < 2, to obtain
j
a desired X() spectral value. So on the unit circle with z = e we have:

Copyright © Richard Lyons 2018 7


N 1 X(m) 1  ejN
X()  X(z) j   N 
z=e
m 0 1  ej2m/N ej

N  1 X(m) 1  ejN
  N  . (B-6)
m 0 1  ej(-2m/N )

We can now simplify Eq. (B-6)—here's the clever step. If we multiply and
divide the numerator and denominator of Eq. (B-6)'s right hand side by the
appropriate half-angled exponentials, we break the exponentials into two
parts and obtain:

N  1 X(m)
X()   

ejN/2 ejN/2  ejN/2
.
 (B-7)
m 0
N e 
j(/2-m/N) ej(/2-m/N)  ej(/2-m/N)

 
Using Euler's equation: 2jsin()= (e -e- ) we can rewrite Eq. (B-7) as:

N 1 X(m) ejN/2(2j)sin(N/2)
X()   N  j(/2-m/N)
m 0 e (2j)sin(/2-m/N)

N  1 X(m) ej(N -1)/2 sin(N/2)


  N  jm/N . (B-8)
m 0 e sin(/2-m/N )

Equation (B-8) is Eq. (2.142) in [2]. Next, when we determine our value for 
based on k, where  = 2k/N, we have:

N 1 X(m) ej(2k/N )
[(N -1)/2] sin(k)
X(k)   N 
m 0 ejm/N sin[(2k/N)/2-m/N]

N 1 X(m) ej(2k/N)[(N -1)/2] sin(k)


  N  jm/N sin[(k-m)/N]
. (B-9)
m 0 e

Appendix C: Derivation of Eq. (3)


This appendix shows the derivation of the above Eq. (3). We begin by using
the Eq. (B-5) from Appendix B, the z-transform of the x(n) time-domain
sequence, repeated here as Eq. (C-1):

N  1 X(m) 1  zN
X(z)   N  . (C-1)
m 0 1  ej2m/N z1

Equation (C-1) tells us how to compute X(z), for any z, using our X(m) DFT
samples. Now all we have to do is evaluate Eq. (C-1) on the z-plane's unit
circle at a frequency of 2k/N radians to obtain our desired X(k) spectral
j2k/N
value. On the unit circle with z = e we have:

Copyright © Richard Lyons 2018 8


N  1 X(m) 1  ej2k
X(k)  X(z) j2k/N   N 
z=e
m 0 1  ej2m/N ej2k/N

N  1 X(m) 1  e j2k
  N  . (C-2)
m 0 1  ej2(k  m)/N

Again, keep in mind that our DFT bin index-like frequency variable k, where
0 ≤ k ≤ N-1, is not restricted to be an integer.

Copyright © Richard Lyons 2018 9

You might also like