Download as docx, pdf, or txt
Download as docx, pdf, or txt
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