Discrete Signal Processing (DSP):
Discrete Fourier Transformation (DFT)
Table of Contents
$$
Av=\lambda v$$
$\quad\;$ where $h$ is the impulse response
Stack $N$ normalized harmonic sinusoid $\{s_k\}_{k=0}^{N-1}$ as columns into an $N\times N$ complex orthonormal basis matrix
%plot -s 800,500
% visualize S matrix
N = 16;
n = 0:N-1;
k = 0:N-1;
S = 1/sqrt(N)*exp(1j*2*pi/N).^(n'*k);
subplot(1,2,1), imagesc(n,k,real(S)); colormap('jet'); axis('square');
title('real part'), xlabel('k'), ylabel('n')
subplot(1,2,2), imagesc(n,k,imag(S)); colormap('jet'); axis('square');
title('imaginary part'), xlabel('k'), ylabel('n')
A basis $\{b_k\}$ for a vector space $V$ is a collection of vectors from $V$ that linearly independent and span $V$
$$
\begin{align*}
B^H B = \begin{bmatrix}
b_0^H\\
b_1^H\\
\vdots\\
b_{N-1}^H
\end{bmatrix} \left[b_0 \mid b_1 \mid b_2 \mid \cdots \mid b_{N-1} \right]
\end{align*} =
\begin{bmatrix}
1 & \\
& 1\\
& & \ddots\\
& & & 1
\end{bmatrix}
$$
Given an orthonormal basis $\{b_k\}_{k=0}^{N-1}$ and orthonormal basis matrix $B$, signal representation for any signal $x$
Stack $N$ normalized harmonic sinusoid $\{s_k\}_{k=0}^{N-1}$ as columns into an $N\times N$ complex orthonormal basis matrix
$$
\begin{align*}
S = \left[s_0 \mid s_1 \mid \cdots \mid s_{N-1} \right] \quad \text{where}\quad s_k[n] = \frac{1}{\sqrt{N}}e^{j\frac{2\pi}{N}kn}
\end{align*}
$$
$$S^H S = I \implies \langle s_k,s_l\rangle \, =\, 0 \quad k\, \neq l,\quad \text{and}\quad \lVert s_k \rVert_2\, =\, 1$$
Jean Baptiste Joseph Fourier had the radical idea of proposing that all signals could be represented as a linear combination of sinusoids.
DFT
The weight $X[k]$ measures the similarity between $x$ and the harmonic sinusoid $s_k$
It finds the “frequency content” of $x$ at frequency $k$
Inverse DFT
Unnormalized DFT
%% DFT without using the built-in function
x = [1 -1 -1 0 0 0 1 -1];
N = length(x);
X = zeros(1,N);
for k = 0:N-1
for n = 0:N-1
X(k+1) = X(k+1) + x(n+1)*exp(-1j*2*pi/N*n*k);
end
end
X
%plot -s 560,600
% plot a discrete-time signal
xn = 0:N-1;
k = 0:N-1;
subplot(3,1,1),
stem(xn,x,'filled'), ylabel('x[n]')
subplot(3,1,2),
stem(k,real(X),'filled'), ylabel('Real of X[k]')
subplot(3,1,3),
stem(k,imag(X),'filled'), ylabel('Imaginary of X[k]')
%plot -s 560,400
% plot a discrete-time signal
subplot(2,1,1),
stem(xn,x,'filled'), ylabel('x[n]')
subplot(2,1,2),
stem(k,abs(X),'filled'), ylabel('|X[k]|')
Unnormalized DFT
function [Xk] = dft(xn,N)
% Computes Discrete Fourier Transform
% [Xk] = dft(xn,N)
% Xk = DFT coeff. array over 0 <= k <= N-1
% xn = N-point finite-duration sequence
% N = Length of DFT
%
n = [0:1:N-1]; % row vector for n
k = [0:1:N-1]; % row vecor for k
WN = exp(-1j*2*pi/N); % Wn factor
nk = n'*k; % creates a N by N matrix of nk values
WNnk = WN.^nk; % DFT matrix
Xk = xn*WNnk; % row vector for DFT coefficients
%plot -s 560,420
k = 3; % index for freqeuncy
N = 8;
n = 0:N-1; % sampling period
x = exp(1j*2*pi/N*k*n); % harmonic complex exponential
plot(real(x),imag(x),'o','MarkerFaceColor','b')
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
X = dft(x,N);
%X = fft(x,N);
subplot(2,1,1), stem(n,real(x),'filled'), axis tight
xlabel('n'), ylabel('x[n]')
title(['Re(e^{(j2\pi/N kn)}), k = ',num2str(k)])
subplot(2,1,2); stem(n,abs(X),'filled'), axis tight
xlabel('k')
ylabel('Amplitude of X[k]')
title('Result of FFT')
%plot -s 560,600
% Normalized DFT
k = 2; % index for freqeuncy
N = 8;
n = 0:N-1; % sampling period
x = exp(1j*2*pi/N*k*n); % harmonic complex exponential
X = dft(x,N)/N;
subplot(3,1,1), stem(n,real(x),'filled')
xlabel('n'), ylabel('Re\{x[n]\}')
title(['e^{(j2\pi/N kn)}, k = ',num2str(k)],'Fontsize',8)
subplot(3,1,2), stem(n,imag(x),'filled')
xlabel('n'), ylabel('Im\{x[n]\}')
title(['e^{(j2\pi/N kn)}, k = ',num2str(k)],'Fontsize',8)
subplot(3,1,3); stem(n,abs(X),'filled')
xlabel('k','Fontsize',8)
ylabel('Amplitude','Fontsize',8)
title('DFT','fontsize',8)
%plot -s 560,400
k = 1; % index for freqeuncy
N = 8;
n = 0:N-1; % sampling period
x = cos(2*pi/N*k*n); % harmonic complex exponential
X = dft(x,N)/N;
subplot(2,1,1), stem(n,real(x),'filled')
xlabel('n'), ylabel('x[n]'), xlim([0,8])
title(['sin{(2\pi/N kn)}, k = ',num2str(k)],'Fontsize',8)
subplot(2,1,2); stem(n,abs(X),'filled'), ylim([0,1]), xlim([0,8])
xlabel('k','Fontsize',8)
ylabel('Amplitude','Fontsize',8)
title('DFT','fontsize',8)
Typical interval 1: $0\leq k \leq N-1$ corresponds to frequencies $\omega_k$ in the interval $0 \leq \omega \leq 2\pi$
Typical interval 2: $-\frac{N}{2}\leq k \leq \frac{N}{2}-1$ corresponds to frequencies $\omega_k$ in the interval $-\pi \leq \omega \leq \pi$
n = 0:N-1;
k = 0:N-1;
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
X = fft(x,N)/N;
Xs = fftshift(X);
subplot(2,1,1); stem(n,abs(X),'filled'), ylim([0,1]), xlim([0,8])
xlabel('k','Fontsize',8)
ylabel('Amplitude','Fontsize',8)
title('DFT','fontsize',8)
subplot(2,1,2); stem(ks,abs(Xs),'filled'), ylim([0,1]), xlim([-4,4])
xlabel('k','Fontsize',8)
ylabel('Amplitude','Fontsize',8)
title('Shifted DFT','fontsize',8)
DFT pair
DFT Frequencies
%plot -s 560,600
%% DFT (FFT) example
N = 16;
h = zeros(1,N);
h(1:8) = 1;
n = 0:N-1;
k = 0:N-1;
X = fft(h,N)/N;
Xs = fftshift(X);
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
subplot(3,1,1),
stem(n,h,'filled'), xlabel('n'), ylabel('x[n]')
subplot(3,1,2),
stem(k,abs(X),'filled'), xlabel('k'), ylabel('abs(X[k])')
subplot(3,1,3),
stem(ks,abs(Xs),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2-1])
DFT and Circular Shift
%plot -s 800,600
%% DFT and circular shift
N = 16;
h = zeros(1,N);
h(1) = 1;
h2 = cirshftt(h,1,N);
n = 0:N-1;
k = 0:N-1;
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
X = fft(h,N);
Xs = fftshift(X);
X2 = fft(h2,N);
X2s = fftshift(X2);
subplot(3,2,1),
stem(n,h,'filled'), xlabel('n'), ylabel('x[n]')
subplot(3,2,3),
stem(ks,abs(Xs),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2-1])
subplot(3,2,5),
stem(ks,phase(Xs),'filled'), xlabel('k'), ylabel('phase(X[k])'), ylim([-5,5])
xlim([-N/2,N/2-1]), ylim([-5,5])
subplot(3,2,2),
stem(n,h2,'filled'), xlabel('n'), ylabel('x[n]')
subplot(3,2,4),
stem(ks,abs(X2s),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2-1])
subplot(3,2,6),
stem(ks,phase(X2s),'filled'), xlabel('k'), ylabel('phase(X[k])'), xlim([-N/2,N/2-1]), ylim([-5,5])
DFT and Modulation
%plot -s 800,400
%% DFT and modulation
N = 16;
h = zeros(1,N);
h(1:8) = 1;
h2 = zeros(1,N);
for i = 1:N
h2(i) = (-1)^i*h(i);
end
n = 0:N-1;
k = 0:N-1;
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
X = fft(h,N);
Xs = fftshift(X);
X2 = fft(h2,N);
X2s = fftshift(X2);
subplot(2,2,1),
stem(n,h,'filled'), xlabel('n'), ylabel('x[n]')
subplot(2,2,3),
stem(ks,abs(Xs),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2-1])
subplot(2,2,2),
stem(n,h2,'filled'), xlabel('n'), ylabel('x[n]')
subplot(2,2,4),
stem(ks,abs(X2s),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2-1])
DFT and Circular Convolution
%plot -s 560,400
%% low-pass filter
N = 16;
h = zeros(1,N);
h(1:3) = 1;
n = 0:N-1;
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
X = fft(h,N)/N;
Xs = fftshift(X);
subplot(2,1,1),
stem(n,h,'filled'), xlabel('n'), ylabel('x[n]')
subplot(2,1,2),
stem(ks,abs(Xs),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2]), ylim([0,0.5])
%plot -s 560,400
%% high-pass filter
N = 16;
h = zeros(1,N);
h(1) = 1;
h(2) = -1;
n = 0:N-1;
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
X = fft(h,N)/N;
Xs = fftshift(X);
subplot(2,1,1),
stem(n,h,'filled'), xlabel('n'), ylabel('x[n]')
subplot(2,1,2),
stem(ks,abs(Xs),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2]), ylim([0,0.5])
%plot -s 560,400
%% band-pass filter
N = 16;
h = zeros(1,N);
h(1) = 1;
h(2) = 0;
h(3) = -1;
n = 0:N-1;
kr = [0:N/2-1 -N/2:-1];
ks = fftshift(kr);
X = dft(h,N)/N;
Xs = fftshift(X);
subplot(2,1,1),
stem(n,h,'filled'), xlabel('n'), ylabel('x[n]')
subplot(2,1,2),
stem(ks,abs(Xs),'filled'), xlabel('k'), ylabel('abs(X[k])'), xlim([-N/2,N/2-1]), ylim([0,0.5])
%plot -s 560,800
N = 50;
n = 0:N-1;
s = sin(pi/N*n) .* [ones(1,N/2), -ones(1,N/2)];
subplot(4,1,1)
stem(s,'b','Marker','none','LineWidth',2);
axis([1 N -1.5 1.5])
title('piecewise smooth signal','fontsize',8)
% add noise to the signal
x = s + 0.1*randn(1,N);
subplot(4,1,2)
stem(x,'b','Marker','none','LineWidth',2);
axis([1 N -1.5 1.5])
title('piecewise smooth signal + noise','fontsize',8)
% construct moving average filter impulse response of length M
M = 5;
h = ones(1,M)/M;
subplot(4,1,3)
stem(h,'b','Marker','none','LineWidth',2);
axis([1 N 0 1])
title('impulse response','fontsize',8)
% convolve noisy signal with impulse response
y = cconv(x,h,N);
subplot(4,1,4)
stem(y,'b','Marker','none','LineWidth',2);
axis([1 N -1.5 1.5])
title('output','fontsize',8)
%plot -s 800,400
k = n;
H = fft(h,N);
X = fft(x,N);
Y = H.*X;
yi = ifft(Y);
subplot(2,1,1)
stem(n,y,'b','Marker','none','LineWidth',2);
subplot(2,1,2)
stem(n,yi,'b','marker','none','LineWidth',2)
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')