You are on page 1of 19

Indian Institute of Technology Patna

Department of Electrical Engineering

EE321
Digital Signal Processing Laboratory

Experiment 4

Discrete Fourier Transform

Name/ Roll no.

Piyush Tewari: 2101EE94

Debashish Kalita: 2101EE95

Abhraneel Saha: 2101EE96

Date: 28-02-2024

Group no. 14
Aim 1: Find the DFT and IDFT of the given sequence using definitions. Say, x[n] = {0, 1, 2,
3}

x_n = [0 1 2 3];
length = length(x_n);
x_k = zeros (1, length);
tw = exp((-1j*2*pi)/length);
for k = 0:1:(length-1)
for n = 0:1:(length-1)
var = x_n(n+1)*(tw^(n*k));
x_k(k+1) = x_k(k+1) + var;
end
end
disp(x_n);
disp(x_k);
%Displayed Output:
Input: 0 1 2 3
DFT: 6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 - 0.0000i -2.0000 - 2.0000i

clear
x_k = [6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 - 0.0000i -2.0000 - 2.0000i];
length = length(x_k);
x_n = zeros (1, length);
tw = exp((1j*2*pi)/length);
for n = 0:1:(length-1)
for k = 0:1:(length-1)
var = x_k(k+1)*(tw^(n*k));
x_n(n+1) = x_n(n+1) +var;
end
end
x_n = x_n/length;
disp(x_k);
disp(x_n);

%Displayed Output:
Input: 6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 + 0.0000i -2.0000 - 2.0000i

IDFT: 0.0000 + 0.0000i 1.0000 + 0.0000i 2.0000 - 0.0000i 3.0000 - 0.0000i

Aim 2: Repeat Aim 1 using compact matrix representation.

%AIM 2: USNIG MATRIX METHOD: DFT


clear
x_n = [0 1 2 3]';
length = length(x_n);
D_N = zeros(length);
tw = exp((-1j*2*pi)/length);
for k = 0:1:(length-1)
for n = 0:1:(length-1)
D_N(k+1,n+1) = tw^(n*k);
end
end
x_k = D_N * x_n;
disp(x_n);
disp(x_k);

Input:
0
1
2
3
DFT:
6.0000 + 0.0000i
-2.0000 + 2.0000i
-2.0000 - 0.0000i
-2.0000 - 2.0000i
%%
%AIM 2: USNIG MATRIX METHOD: IDFT
clear
x_k = [6.0000+0.0000i; -2.0000+2.0000i; -2.0000-0.0000i; -2.0000-2.0000i];
length = length(x_k);
D_N = zeros(length);
tw = exp((1j*2*pi)/length);
for n = 0:1:(length-1)
for k = 0:1:(length-1)
D_N(k+1,n+1) = tw^(n*k);
end
end
x_n = (D_N * x_k)/length;
disp(x_k);
disp(x_n);

Input:
6.0000 + 0.0000i
-2.0000 + 2.0000i
-2.0000 + 0.0000i
-2.0000 - 2.0000i
IDFT:
0.0000 + 0.0000i
1.0000 + 0.0000i
2.0000 - 0.0000i
3.0000 - 0.0000i
Aim 3: Consider Aim 1 and Aim 2 and write "C" program to verify using Code Composer
Studio (CCS-3.1) IDE and the DSP TMS 320C6713 DSK Kit.

%dft
#include<stdio.h>
#include<math.h>
float x_n[4] = {0,1,2,3};
float x_k_real[4]= {0,0,0,0};
float x_k_img[4]= {0,0,0,0};
int i = 0;
int j = 0;
int main(void){
for(i=0; i< 4; i++){
for(j=0; j<4; j++){
x_k_real[i] += x_n[j]* cos(2* 3.14 * i * j /4);
x_k_img[i] += -1 * x_n[j]* sin(2* 3.14 * i * j /4);
}
}
return 0;
}

%idft
#include<stdio.h>
#include<math.h>
float x_n[4] = {0,0,0,0};
float x_k_real[4]= {6,-2,-2,-2};
float x_k_img[4]= {0,2,0,-2};
int i = 0;
int j = 0;
int main(void){
for(i=0; i< 4; i++){
for(j=0; j<4; j++){
x_n[i] = 0.25*(x_k_real[j]* cos(2* 3.14 * i * j /4) - x_k_img[j]* sin(2*
3.14 * i * j /4));
}
}
return 0;
}
MATLAB Code:

FFT:
N-Point FFT Using Decimation in Time(DIT) Technique:
function X = DIT_FFT(x)
len = length(x);
wn = exp(-1i*pi*2*(0:len/2-1)/len);
if len == 1
X = x;
else
even = x(1:2:end);
odd = x(2:2:end);
Y0 = DIT_FFT(even);
Y1 = DIT_FFT(odd);
X = [Y0+Y1.*wn, Y0-Y1.*wn];
end
end

IFFT:
N-Point IFFT Using Decimation in Time(DIT) Technique:
function X = isolve(x)

N = length(x);

if N == 1

X = x;

return;

end
x_even = x(1:2:N);

x_odd = x(2:2:N);

X_even = isolve(x_even);

X_odd = isolve(x_odd);

X = zeros(1,N);

w = zeros(1,N/2);

for k = 1:N/2

w(k) = exp(2i*pi*(k-1)/N);

end

for k = 1:N/2

X(k) = X_even(k) + w(k)*X_odd(k);

X(k+N/2) = X_even(k) - w(k)*X_odd(k);

end

end

% Calling FFT and IFFT functions

x=[0,1,2,3];

N = length(x) ;

y = solve(x) ;

XX=isolve(y)/N;

XX

FFT of x(n)=[1,2,3,4]:
y= 6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 - 0.0000i -2.0000 -
2.0000i
IFFT of y:
XX= 0.0000 + 0.0000i 1.0000 + 0.0000i 2.0000 + 0.0000i 3.0000 -
0.0000i

MATLAB Code:

FFT:
N-Point FFT Using Decimation in Frequency(DIF) Technique:

% Input sequence

x = [0, 1, 2, 3];

N = length(x); % Length of input sequence

% Calculate the number of stages

p = log2(N);

% Initializations

Half = N / 2; % Half of the sequence length

% Loop over each stage

for stage = 1:p

% Loop over each group within the stage

for index = 0:(N / (2^(stage-1))):(N-1)

% Loop over each butterfly within the group

for n = 0:(Half-1)

% Calculate the position in the sequence


pos = n + index + 1;

% Calculate the twiddle factor

pow = (2^(stage-1)) * n;

w = exp((-1i) * (2*pi) * pow / N);

% Perform butterfly operation

a = x(pos) + x(pos + Half); % Addition

b = (x(pos) - x(pos + Half)) .* w; % Multiplication with twiddle factor

% Update the sequence with the butterfly result

x(pos) = a;

x(pos + Half) = b;

end

end

Half = Half / 2; % Halve the Half for the next stage

end

% Bit-reverse order the output

y = bitrevorder(x);

% Display the output

disp(y);

FFT of x(n)=[1,2,3,4]:

y= 6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 - 0.0000i -2.0000 -


2.0000i

IFFT:
N-Point IFFT Using Decimation in Frequency (DIF) Technique:

x = [6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 + 0.0000i -2.0000 - 2.0000i] ;

N = length(x);
p=log2(N);

Half=N/2;

for stage=1:p

for index=0:(N/(2^(stage-1))):(N-1)

for n=0:(Half-1)

pos=n+index+1;

pow=(2^(stage-1))*n;

w=exp((1i)*(2*pi)*pow/N);

a=x(pos)+x(pos+Half);

b=(x(pos)-x(pos+Half)).*w;

x(pos)=a;

x(pos+Half)=b;

end

end

Half=Half/2;

end

y=bitrevorder(x)/N;

IFFT of y:
y= 0.0000 + 0.0000i 1.0000 + 0.0000i 2.0000 + 0.0000i 3.0000 -
0.0000i

Output of IFFT of x(n):

IDFT of x[k]
Output of FFT of x(n):
C code Using DIT:

FFT:
N-Point FFT Using Decimation in Time(DIT) Technique:
#include <stdio.h>

#include <stdlib.h>

#include <math.h>

void solve(double *x_re, double *x_im, double *X_re, double *X_im, int N) {

% Base case: If the length of the input is 1, return the input itself

if (N == 1) {

X_re[0] = x_re[0];
X_im[0] = x_im[0];

return;

% Allocate memory for even and odd parts of the input sequence

double *x_even_re = (double*)malloc((N/2) * sizeof(double));

double *x_even_im = (double*)malloc((N/2) * sizeof(double));

double *x_odd_re = (double*)malloc((N/2) * sizeof(double));

double *x_odd_im = (double*)malloc((N/2) * sizeof(double));

% Split the input into even and odd indices

for (int i = 0; i < N/2; i++) {

x_even_re[i] = x_re[2*i];

x_even_im[i] = x_im[2*i];

x_odd_re[i] = x_re[2*i+1];

x_odd_im[i] = x_im[2*i+1];

% Recursively compute FFT for even and odd parts of the input

solve(x_even_re, x_even_im, X_re, X_im, N/2);

solve(x_odd_re, x_odd_im, X_re + N/2, X_im + N/2, N/2);

% Allocate memory for twiddle factors

double *w_re = (double*)malloc((N/2) * sizeof(double));

double *w_im = (double*)malloc((N/2) * sizeof(double));

% Calculate twiddle factors

for (int k = 0; k < N/2; k++) {

w_re[k] = cos(-2*M_PI*k/N);

w_im[k] = sin(-2*M_PI*k/N);

% Combine results using twiddle factors


for (int k = 0; k < N/2; k++) {

double t_re = w_re[k] * X_re[k + N/2] - w_im[k] * X_im[k + N/2];

double t_im = w_re[k] * X_im[k + N/2] + w_im[k] * X_re[k + N/2];

X_re[k] = X_re[k] + t_re;

X_im[k] = X_im[k] + t_im;

X_re[k + N/2] = X_re[k] - 2*t_re;

X_im[k + N/2] = X_im[k] - 2*t_im;

% Free allocated memory

free(x_even_re);

free(x_even_im);

free(x_odd_re);

free(x_odd_im);

free(w_re);

free(w_im);

int main() {

% Input sequence

double x_re[] = {0, 1, 2, 3};

double x_im[] = {0, 0, 0, 0};

int N = sizeof(x_re) / sizeof(x_re[0]); // Length of input sequence

% Allocate memory for output sequence

double *X_re = (double*)malloc(N * sizeof(double));

double *X_im = (double*)malloc(N * sizeof(double));

% Compute FFT

solve(x_re, x_im, X_re, X_im, N);


FFT of x(n)=[1,2,3,4]:

X(k)= 6.0000 + 0.0000i -2.0000 + 2.0000i -2.0000 - 0.0000i -2.0000 -


2.0000i

IFFT:
N-Point IFFT Using Decimation in Time(DIT) Technique:
#include <stdio.h>

#include <math.h>

#include <stdlib.h>

#include <complex.h>

#define PI 3.14159265358979323846

% Function prototype

void isolve(double complex *x, double complex *X, int N);

int main() {

int N = 4; % Number of complex numbers

double complex x[] = {6.0000 + 0.0000*I, -2.0000 + 2.0000*I, -2.0000 + 0.0000*I, -2.0000 - 2.0000*I};
double complex X[N];

% Call the IFFT function

isolve(x, X, N);

% Printing the results

printf("Result of IFFT:\n");

for (int i = 0; i < N; i++) {

% Normalize the result by dividing by N

printf("%f + %fi\n", creal(X[i])/N, cimag(X[i])/N);

return 0;

% Recursive IFFT function

void isolve(double complex *x, double complex *X, int N) {

% Base case: if N is 1, the IFFT is simply the input value

if (N == 1) {

X[0] = x[0];

return;

% Split the input array into even and odd indices

double complex x_even[N/2];

double complex x_odd[N/2];

double complex X_even[N/2];

double complex X_odd[N/2];

for (int i = 0; i < N/2; i++) {

x_even[i] = x[2*i];

x_odd[i] = x[2*i+1];

% Recursively compute the IFFT for even and odd indices

isolve(x_even, X_even, N/2);

isolve(x_odd, X_odd, N/2);

% Compute twiddle factors

double complex w[N/2];


for (int k = 0; k < N/2; k++) {

w[k] = cexp(2.0 * PI * I * k / N);

% Combine results

for (int k = 0; k < N/2; k++) {

X[k] = X_even[k] + w[k] * X_odd[k];

X[k + N/2] = X_even[k] - w[k] * X_odd[k];

IFFT of X(k):
X(n)= 0.0000 + 0.0000i 1.0000 + 0.0000i 2.0000 + 0.0000i 3.0000 -
0.0000i

Output of Real and Imaginary Parts of FFT:

Real part of x[k]:


Imaginary part of x[k]:

Output of Real and Imaginary Parts of IFFT:

Real Part of x(n):


Imaginary Part of x(n):

You might also like