You are on page 1of 10

Lab-9

Abstract:

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


DIF (Decimation in Frequency) algorithms in Python. For the Radix3-DIT I first
created a recursive function which takes a sequence and an integer N( which
should be in the form of 3v). 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 Radix3-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 3 (DIT):

The radix-3 DIT FFT algorithm works by recursively breaking down the
input sequence of N complex numbers into three smaller subsequences of
length N/3 each. This process continues until the subsequences are of
length 1, which are trivially their own DFTs.

The three smaller subsequences are then combined using a set of three
twiddle factors, which are complex numbers that depend on the position in
the sequence and the length of the DFT being computed. The resulting
sequence is the DFT of the original sequence.

One advantage of the radix-3 DIT FFT algorithm over the radix-2 DIT FFT
algorithm is that it requires fewer arithmetic operations for a given
sequence length. This can result in faster computation times for certain
lengths.
Radix 3 (DIF):

The radix-3 DIF FFT algorithm works by recursively combining three


smaller DFTs of length N/3 into a single DFT of length N. This process
continues until the full DFT of the sequence is computed.

The algorithm uses a set of three twiddle factors to combine the smaller
DFTs, and these twiddle factors are complex numbers that depend on the
position in the sequence and the length of the DFT being computed.

One advantage of the radix-3 DIF FFT algorithm over the radix-2 DIF FFT
algorithm is that it can be more memory efficient, as it requires less
temporary storage for intermediate results. However, it can require more
arithmetic operations for a given sequence length, which can result in
slower computation times for certain lengths.

The radix-3 FFT algorithm has a complexity of O(N*log(N)), where N is the


length of the input sequence.

Procedure:

DIT:

Define a function, say "ganni_radix3dit(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 1, compute and return the DFT of "x" directly as x.

Otherwise, split "x" into 3 parts as x(3k), x(3k+1), x(3k+2).

Recursively compute the DFTs of the parts by calling the "ganni_radix4dit"


function with "N/3" as the length argument after applying certain operations on
them according to the formula.
Compute the DFT of x by combining the results obtained from the previous step
for the 3 parts.

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 3, add zeros to the end of the
signal until its length becomes a power of three.

Divide the signal into three parts with consecutive 3rd elements.

Recursively apply the DFT to each of the three parts.

Combine the results of the three sub-transforms using the butterfly structure.

According to the butterfly structure of the Radix 3 DIF, combine the three parts.

Finally return the output.

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 Radix3-(DIT) and Radix3-(DIF) algorithms in


Python.

References:

1. Sanghavi, Rohan. “RADIX 3 FFT TOOLBOX - File Exchange - MATLAB


Central.” MathWorks, 5 September 2020,
https://in.mathworks.com/matlabcentral/fileexchange/79921-radix-3-fft-
toolbox. Accessed 8 April 2023.

2. “Radix 3 DIF” Texas Instruments,` 11 April 2019,


https://www.ti.com/lit/ml/spra152/spra152.pdf?ts=1679767852078.
Accessed 8 April 2023.

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

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

def ganni_radix3dit(x, N=None):


if N is None:
N = len(x)
if(N == 1):
return x
else:
x1 = x[::3]
x2 = x[1::3]
x3 = x[2::3]
X1 = ganni_radix3dit(x1, N/3)
X2 = ganni_radix3dit(x2, N/3)
X3 = ganni_radix3dit(x3, N/3)
N = int(N)
l = [0]*N
z = 0
for _ in range(3):
for (i, j, k) in zip(X1, X2, X3):
l[z] = i + (j*W(N)**(z)) + (k*W(N)**(2*z))
z += 1
return l

def ganni_radix3dif(x, N=None):


val = np.sqrt(3)*1j
if N is None:
N = len(x)
if(N == 1):
print(x)
return x
x0 = np.array(x[:N//3])
x1 = np.array(x[N//3:(2*N)//3])
x2 = np.array(x[(2*N)//3:])

print(x0, x1, x2)

x0_ = []
x1_ = []
x2_ = []
for (k, (i_, j_, k_)) in enumerate(zip(x0, x1, x2)):
x0_.append(i_+j_+k_)
x1_.append((i_ + (j_*(-1-val)/2) + (k_*(-1+val)/2))*W(N)**k)
x2_.append((i_ + (j_*(-1+val)/2) + (k_*(-1-
val)/2))*W(N)**(2*k))

X0 = ganni_radix3dif(x0_, N//3)
X1 = ganni_radix3dif(x1_, N//3)
X2 = ganni_radix3dif(x2_, N//3)
Y = []
for i in range(len(X0)):
Y.append(X0[i])
Y.append(X1[i])
Y.append(X2[i])
return Y

N = 243
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)

Y = np.fft.fft(x)
Y1 = ganni_radix3dif(x, N)
Y2 = ganni_radix3dif(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(2, 1, 1)
p1m = plt.stem(f, Y1m)[0].axes
p1m.set_ylabel('|Y|')
p1m.set_title('|Y| vs f - (DIT)')

plt.subplot(2, 1, 2)
p1a = plt.stem(f, Y1a)[0].axes
p1a.set_ylabel('ang(Y)')
p1a.set_title('ang(Y) vs f - (DIT)')

plt.tight_layout()
plt.show()

You might also like