0% found this document useful (0 votes)
72 views

Lab 7

The document describes implementing the radix-2 decimation in time (DIT) and decimation in frequency (DIF) algorithms for computing the discrete Fourier transform (DFT) in Python. For radix-2 DIT, the input is recursively divided into halves and the DFT is computed for each half. For radix-2 DIF, the DFT is computed recursively starting with pairs of samples and combining results. Both algorithms have O(n log n) complexity. Test signals were transformed with both algorithms and matched the traditional DFT, verifying the implementations.

Uploaded by

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

Lab 7

The document describes implementing the radix-2 decimation in time (DIT) and decimation in frequency (DIF) algorithms for computing the discrete Fourier transform (DFT) in Python. For radix-2 DIT, the input is recursively divided into halves and the DFT is computed for each half. For radix-2 DIF, the DFT is computed recursively starting with pairs of samples and combining results. Both algorithms have O(n log n) complexity. Test signals were transformed with both algorithms and matched the traditional DFT, verifying the implementations.

Uploaded by

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

Lab-7

Abstract:

In this experiment we implemented the radix-2 in DIT (Decimation in Time) and


DIF (Decimation in Frequency) algorithms in Python. For the Radix2-DIT I first
created a recursive function which takes a sequence and an integer N( which
should be in the form of 2v). Then the input is decimated in time and the DFT of
both halves are again calculated recursively and the end result is combined
appropriately. The same is done with the Radix2-DIF but this time decimation is
done in frequency, that is the output sequence is decimated. I have then tested
both the functions with a given signal and verified if the results are matching with
the traditional DFT calculation. It is observed that the DIT algorithm was slightly
faster for smaller input sizes, while the DIF algorithm was faster for larger input
sizes.

Introduction:

Radix 2 (DIT):

Radix-2 Decimation in Time (DIT) is an algorithm used for computing the


Discrete Fourier Transform (DFT) of a sequence of n complex numbers. It is
called "radix-2" because it uses a base-2 decomposition of the DFT. The
algorithm works by repeatedly breaking down the DFT into smaller subproblems.
It does this by splitting the input sequence into two halves and computing the
DFT of each half separately. The sub-DFTs are then combined using a series of
butterfly operations, which involves adding and subtracting the values of the sub-
DFTs multiplied by complex exponentials.

At each stage of the algorithm, the input sequence is divided into 2^(k-1) pairs of
numbers, where k is the stage number (starting from 1). Each pair of numbers
corresponds to a butterfly operation. The complex exponential used in the
butterfly operation is determined by the index of the pair and the stage number.

The butterfly operation is performed by multiplying the second number in the pair
by the complex exponential, and adding or subtracting the result to the first
number in the pair, depending on whether the index of the pair is even or odd.
The result is then stored in the first number of the pair. The algorithm continues
until the input sequence is divided into individual numbers, at which point the
DFT has been computed. The final output is a sequence of n complex numbers,
which represent the frequency-domain representation of the input sequence.

The Radix-2 DIT algorithm has a computational complexity of O(n log n), which is
much faster than the brute-force O(n^2) algorithm for computing the DFT

Radix 2 (DIF):

Radix-2 Decimation in Frequency (DIF) is another algorithm used for computing


the Discrete Fourier Transform (DFT) of a sequence of n complex numbers. Like
the DIT algorithm, it is called "radix-2" because it uses a base-2 decomposition of
the DFT. The algorithm works by recursively breaking down the DFT into smaller
subproblems, but unlike the DIT algorithm, it starts with the smallest subproblem
and works its way up to the full DFT. It does this by first computing the DFT of
pairs of adjacent samples, then pairs of 2 samples, then pairs of 4 samples, and
so on until the full DFT is computed.

At each stage of the algorithm, the input sequence is divided into 2^(k-1) blocks
of 2^k samples each, where k is the stage number (starting from 1). Each block
corresponds to a butterfly operation, which involves adding and subtracting the
values of the sub-DFTs multiplied by complex exponentials.

The complex exponential used in the butterfly operation is determined by the


index of the block and the stage number. The output of each butterfly operation is
stored in the first half of the block, while the second half is left unchanged. The
algorithm continues until the final stage, where the input sequence is divided into
two blocks of n/2 samples each. The DFT of each block is computed using a
butterfly operation, and the final output is obtained by combining the two sub-
DFTs.

The Radix-2 DIF algorithm also has a computational complexity of O(n log n),
which is much faster than the brute-force O(n^2) algorithm for computing the DFT

Procedure:
DIT:

Define a function, say "ganni_radix2dit(x, N=None)", that takes the input


sequence "x" and its length "N" (which is optional and defaults to "None" in case
of not being passed) as arguments.

If "N" is 2, compute and return the DFT of "x" directly as [x[0]+x[1], x[0]-x[1]].

Otherwise, split "x" into its even and odd-indexed samples, i.e., xe = x[::2] and xo
= x[1::2].

Recursively compute the DFTs of xe and xo by calling the "ganni_radix2dit"


function with "N/2" as the length argument.

Compute the DFT of x by combining the results obtained from the previous step
for xe and xo. Specifically, compute the DFT of x[k] by the formula: X[k] = Xe[k] +
W(N)^k * Xo[k], where Xe and Xo are the DFTs of xe and xo, respectively, and
W(N) is the twiddle factor defined as W(N) = e^(-2pij/N).

Return the computed DFT of "x" as a list of complex numbers.

DIF:

If the length of the input signal is not a power of two, add zeros to the end of the
signal until its length becomes a power of two.

Divide the signal into two parts with alternating elements.

Recursively apply the DFT to each of the two parts.

Combine the results of the two sub-transforms using the butterfly structure:

Add the even-indexed and odd-indexed sub-transforms to get the sum and
difference, respectively.

Multiply the difference by the twiddle factor of the current stage, which is given by
exp(-j2pi*k/N), where k is the index of the current element and N is the length of
the signal.

Combine the sum and the modified difference to get the final result for the current
element.
Results:
Discussions:

Overall I am satisfied with the performance of my code as it was able to


successfully plot the required plots.It is observed that the DIT algorithm
was slightly faster for smaller input sizes, while the DIF algorithm was
faster for larger input sizes. Finally plotted the given signal using both the
methods and verified it with the traditional DFT method. The plots have
matched indicating the implementation of the algorithm is working.

Conclusion:

Successfully implemented the Radix2-(DIT) and Radix2-(DIF) algorithms in


Python.

References:

1. Radix-2 Fast Fourier Transform, MATH3511 - Numerical Analysis II,


Spring semester 2019, 22 January 2019,
https://www.phys.uconn.edu/~rozman/Courses/m3511_19s/downloads/radi
x2fft.pdf. Accessed 19 March 2023.

2. “3.5. DECIMATION IN FREQUENCY (DIF) RADIX 2 FFT: In Radix-2


decimation-in-frequency (DIF) FFT algorithm, original sequence s(n) i.”
Rohini College of Engineering & Technology,
https://www.rcet.org.in/uploads/academics/rohini_87453928097.pdf.
Accessed 19 March 2023.

Appendice:
import numpy as np
from matplotlib import pyplot as plt

def harry_dft(li, N=None):


if N is None:
N = len(li)
Y = [0]*N
for k in range(N):
for n in range(N):
Y[k] = Y[k]+ li[n]*np.exp(-1j*(2*np.pi*k*n)/N)
return Y

def W(N):
return np.exp(-2j*np.pi/N)

def ganni_radix2dit(x, N=None):


n = len(x)
if not ((n & (n-1) == 0) and n != 0):
val = 1
while(val<=n):
val = val << 1
x = list(x) + [0]*(val-n)
if N is None:
N = len(x)
if(N == 2):
return [x[0]+x[1], x[0]-x[1]]
else:
xe = x[::2]
xo = x[1::2]
Xe = ganni_radix2dit(xe, N/2)
Xo = ganni_radix2dit(xo, N/2)
N = int(N)
l = [0]*N
k = 0
for (i, j) in zip(Xe, Xo):
l[k] = i+(j*W(N)**k)
k += 1
for (i, j) in zip(Xe, Xo):
l[k] = i+(j*W(N)**k)
k += 1
return l

def ganni_radix2dif(x, N=None):


n = len(x)
if not ((n & (n-1) == 0) and n != 0):
val = 1
while(val<=n):
val = val << 1
x = list(x) + [0]*(val-n)
if N is None:
N = len(x)
if(N == 2):
return [x[0]+x[1], x[0]-x[1]]
else:
x1 =x[:int(N/2)]
x2 = x[int(N/2):]
X1= [i+j for (i,j) in zip(x1, x2)]
X2 = []
k = 0
for (i, j) in zip(x1, x2):
X2.append((i-j)*(W(N)**k))
k += 1

Xe = ganni_radix2dif(X1)
Xo = ganni_radix2dif(X2)
l = []
for i in range(len(Xe)):
l.append(Xe[i])
l.append(Xo[i])
return l

N = input("Enter the no of samples: ")


N = int(N)
fs = 160
ts = 1/fs
t = np.arange(0, N/fs, ts)

x = [np.cos(20*np.pi*i) for i in t]
x = np.array(x) + np.random.normal(0, 1, len(x))

Y = harry_dft(x)
Y1 = ganni_radix2dit(x, N)
Y2 = ganni_radix2dif(x, N)
Ya = [np.angle(i) for i in Y]
Ym = [abs(i) for i in Y]
Y1a = [np.angle(i) for i in Y1]
Y1m = [abs(i) for i in Y1]
Y2a = [np.angle(i) for i in Y2]
Y2m = [abs(i) for i in Y2]

f = [i*(fs/N) for i in range(len(Y))]

plt.figure()
plt.subplot(3, 1, 1)
pm = plt.stem(f, Ym)[0].axes
pm.set_ylabel('ang(Y)')
pm.set_title('ang(Y) vs f')
plt.subplot(3, 1, 2)
p1m = plt.stem(f, Y1m)[0].axes
p1m.set_ylabel('ang(Y1)')
p1m.set_title('ang(Y1) vs f')
plt.subplot(3, 1, 3)
p2m = plt.stem(f, Y2m)[0].axes
p2m.set_ylabel('ang(Y2)')
p2m.set_title('ang(Y2) vs f')

plt.figure()
plt.subplot(3, 1, 1)
pa = plt.stem(f, Ya)[0].axes
pa.set_ylabel('|Y|')
pa.set_title('|Y| vs f')
plt.subplot(3, 1, 2)
p1a = plt.stem(f, Y1a)[0].axes
p1a.set_ylabel('|Y1|')
p1a.set_title('|Y1| vs f')
plt.subplot(3, 1, 3)
p2a = plt.stem(f, Y2a)[0].axes
p2a.set_ylabel('|Y2|')
p2a.set_title('|Y2| vs f')

plt.show()

You might also like