Discrete Signal Processing (DSP):
Discrete Signals
Table of Contents
A signal $x[n]$ is a function that maps an independent variable to a dependent variable.
In this course, we will focus on discrete-time signals $x[n]$:
plot
for continuous signals in MATLAB
stem
for discrete signals in MATLAB
%plot -s 560,200
t = 0:0.01:2;
x = sin(2*pi*t);
plot(t, x, 'linewidth', 2);
ylim([-1.1 1.1]);
xlabel('t [sec]');
ylabel('x(t)');
%plot -s 560,400
N = 20;
n = 0:N-1;
x = sin(2*pi/N*n);
subplot(2,1,1)
plot(n,x,'o'), axis tight, ylim([-1.2, 1.2])
subplot(2,1,2)
stem(n,x,'filled'), axis tight, ylim([-1.2, 1.2])
$$x[n+mN] = x[n], \qquad \forall m \in \mathbb{Z}$$
%plot -s 560,100
N = 8;
n = 0:N-1;
x = [0 1 2 3 4 3 2 1];
stem(n,x,'filled');
xlabel('n'), ylabel('x[n]')
xlim([-16,23]),
yticks([0,4])
box('off')
%plot -s 560,100
%% periodic using mod
y = [];
n = -16:23;
for i = 1:length(n)
y(i) = x(mod(n(i),N)+1);
end
stem(n,y,'filled'), axis tight
xlabel('n'), ylabel('y[n]')
yticks([0,4])
box('off')
Delta function: $\delta[n]$
$$x[n]=\delta[n-n_0] \quad n_1 \leq n \leq n_2$$impseq(n0,n1,n2)
:
function [x,n] = impseq(n0,n1,n2)
% Generates x(n) = delta(n-n0); n1 <= n,n0 <= n2
% [x,n] = impseq(n0,n1,n2)
if ((n0 < n1) | (n0 > n2) | (n1 > n2))
error('arguments must satisfy n1 <= n0 <= n2')
end
n = [n1:n2];
% x = [zeros(1,(n0-n1)), 1, zeros(1,(n2-n0))];
x = [(n-n0) == 0];
%plot -s 560,400
% delta function
n = [-5:5];
x1 = impseq(0,-5,5);
x2 = 2*impseq(-2,-5,5)-impseq(4,-5,5);
subplot(2,1,1), stem(n,x1,'filled'), axis([-5,5,-1.5,2.5]), ylabel('x_1[n]');
subplot(2,1,2), stem(n,x2,'filled'), axis([-5,5,-1.5,2.5]), xlabel('n'), ylabel('x_2[n]');
Unit step selects part of a signal
Multiplying a signal by a shifted unit step function zeros out its entries for $n<m$
$$y[n] = x[n]u[n-m]$$
Step function: $u[n]$
$$x[n]=u[n-n_0] \quad n_1 \leq n \leq n_2$$stepseq(n0,n1,n2)
:
function [x,n] = stepseq(n0,n1,n2)
% Generates x(n) = u(n-n0); n1 <= n,n0 <= n2
% [x,n] = stepseq(n0,n1,n2)
if ((n0 < n1) | (n0 > n2) | (n1 > n2))
error('arguments must satisfy n1 <= n0 <= n2')
end
n = [n1:n2];
% x = [zeros(1,(n0-n1)), ones(1,(n2-n0+1))];
x = [(n-n0) >= 0];
%plot -s 560,400
% step function
n = -5:30;
x1 = stepseq(0,-5,30) - stepseq(10,-5,30);
x2 = 0.9.^n.*stepseq(0,-5,30);
subplot(2,1,1), stem(n,x1,'filled'), axis tight, ylim([-0.1, 1.1]), yticks([0,1]), ylabel('x_1[n]')
subplot(2,1,2), stem(n,x2,'filled'), axis tight, ylim([-0.1, 1.1]), yticks([0,1]), ylabel('x_2[n]')
There are two natural real-valued sinusoids: $\cos (\omega n + \phi)$ and $\sin(\omega n + \phi)$
Frequency: $\omega$ (units: radians/sample)
Phase: $\phi$ (units: radians)
$\phi$ is a (frequency independent) shift that is referenced to one period of oscillation
function [y,n] = sigshift(x,m,n0)
% implements y(n) = x(n-n0)
% [y,n] = sigshift(x,m,n0)
n = m + n0;
y = x;
function [y,n] = sigfold(x,n)
% implements y(n) = x(-n)
% [y,n] = sigfold(x,n)
y = fliplr(x);
n = -fliplr(n);
function [y,n] = sigadd(x1,n1,x2,n2)
% implements y(n) = x1(n)+x2(n)
% [y,n] = sigadd(x1,n1,x2,n2)
% y = sum sequence over n, which includes n1 and n2
% x1 = first sequence over n1
% x2 = second sequence over n2 (n2 can be different from n1)
n = min(min(n1),min(n2)):max(max(n1),max(n2)); % duration of y(n)
y1 = zeros(1,length(n)); y2 = y1; % initialization
y1(find((n >= min(n1)) & (n <= max(n1)) == 1)) = x1; % x1 with duration of y
y2(find((n >= min(n2)) & (n <= max(n2)) == 1)) = x2; % x2 with duration of y
y = y1 + y2; % sequence addition
function [y,n] = sigmult(x1,n1,x2,n2)
% implements y(n) = x1(n)*x2(n)
% [y,n] = sigmult(x1,n1,x2,n2)
% y = product sequence over n, which includes n1 and n2
% x1 = first sequence over n1
% x2 = second sequence over n2 (n2 can be different from n1)
n = min(min(n1),min(n2)):max(max(n1),max(n2)); % duration of y(n)
y1 = zeros(1,length(n)); y2 = y1;
y1(find(( n>= min(n1)) & (n <= max(n1)) == 1)) = x1; % x1 with duration of y
y2(find(( n>= min(n2)) & (n <= max(n2)) == 1)) = x2; % x2 with duration of y
y = y1 .* y2; % sequence multiplication
%plot -s 560,400
n = -2:10;
x = [1:7,6:-1:1];
[x11,n11] = sigshift(x,n,5);
[x12,n12] = sigshift(x,n,-4);
[x1,n1] = sigadd(2*x11,n11,-3*x12,n12);
subplot(2,1,1), stem(n,x,'filled'), xlim([-6,15]), ylim([-21,14])
subplot(2,1,2), stem(n1,x1,'filled'), axis tight
xlabel('n'), ylabel('x_1(n)')
%plot -s 560,200
[x21,n21] = sigfold(x,n);
[x21,n21] = sigshift(x21,n21,3);
[x22,n22] = sigshift(x,n,2);
[x22,n22] = sigmult(x,n,x22,n22);
[x2,n2] = sigadd(x21,n21,x22,n22);
stem(n2,x2,'filled'), axis tight
xlabel('n'), ylabel('x_2(n)')
Given
$$\begin{align*} x[n]=\{&\;0,1,2,3,0,0,0\}\\ &\uparrow \end{align*}$$%plot -s 560,200
N = 7;
x = [0 1 2 3 0 0 0];
n = 0:N-1;
stem(n,x,'filled')
%plot -s 560,400
[x1,n1] = sigfold(x,n);
subplot(2,1,1), stem(n,x,'filled')
ylabel('x[n]'), axis([-6.5 6.5 -1 4])
subplot(2,1,2), stem(n1,x1,'filled')
ylabel('x[-n]'), axis([-6.5 6.5 -1 4])
%plot -s 560,400
[x2,n2] = sigshift(x,n,2);
subplot(2,1,1), stem(n,x,'filled')
ylabel('x[n]'), axis([-0.5 8.5 -1 4])
subplot(2,1,2), stem(n2,x2,'filled')
ylabel('x[n-2]'), axis([-0.5 8.5 -1 4])
%plot -s 560,460
[x2,n2] = sigshift(x,n,2);
[x3,n3] = sigfold(x2,n2);
[x1,n1] = sigfold(x,n);
[x4,n4] = sigshift(x1,n1,2);
subplot(3,1,1), stem(n,x,'filled')
ylabel('x[n]'), axis([-8.5 8.5 -1 4])
subplot(3,1,2), stem(n3,x3,'filled')
ylabel('x_3[n]'), axis([-8.5 8.5 -1 4])
subplot(3,1,3), stem(n4,x4,'filled')
ylabel('x_4[n]'), axis([-8.5 8.5 -1 4])
$$z_2 = a_2 + b_2i, \quad \vec{z}_2 = \begin{bmatrix} a_2 \\ b_2 \end{bmatrix} $$
Discrete Sinusoids
Consider two sinusoids with two different frequencies
% plot -s 560,400
N = 15;
n = 0:N-1;
x1 = cos(2*pi/N*n);
x2 = cos((2*pi/N + 2*pi)*n);
subplot(2,1,1), stem(n,x1,'filled'), yticks([-1,0,1]), ylabel('x_1[n]')
subplot(2,1,2), stem(n,x2,'filled'), yticks([-1,0,1])
xlabel('n'), ylabel('x_2[n]')
Alias-free frequencies
The only frequencies that lead to unique (distinct) sinusoids lie in an interval of length $2\pi$
Two intervals are typically used in the signal processing
%plot -s 560,600
N = 8;
n = 0:N-1;
xn1 = cos(pi*n);
xn2 = cos(3/2*pi*n);
t = 0:0.1:N-1;
x1 = cos(pi*t);
x2 = cos(3/2*pi*t);
x3 = cos(1/2*pi*t);
subplot(3,1,1),
stem(n,xn1,'filled'), hold on
plot(t,x1,'--','color',[0, 0.4470, 0.7410]), hold off
axis([0,7,-1.5 1.5])
ylabel('x_1[n]', 'fontsize', 12)
subplot(3,1,2),
stem(n,xn2,'filled'), hold on
plot(t,x2,'--','color',[0, 0.4470, 0.7410]), hold off
axis([0,7,-1.5 1.5])
ylabel('x_2[n]', 'fontsize', 12)
subplot(3,1,3),
stem(n,xn2,'filled'), hold on
plot(t,x2,'--','color',[0, 0.4470, 0.7410])
plot(t,x3,'color','r'), hold off
axis([0,7,-1.5 1.5])
ylabel('x_2[n]', 'fontsize', 12)
Key question: which one is a higher frequency?
$$\omega_0 = \pi ~~~ \text{or} ~~~ \omega_0 = \frac{3\pi}{2}$$%plot -s 560,400
N = 8;
n = 0:N-1;
x1 = cos(pi*n);
x2 = cos(3/2*pi*n);
subplot(2,1,1), stem(n,x1,'filled'), axis([0,7,-1.5 1.5]), ylabel('x_1')
subplot(2,1,2), stem(n,x2,'filled'), axis([0,7,-1.5 1.5]), ylabel('x_2')
%plot -s 560,600
N = 32;
n = 0:N-1;
x1 = cos(0*pi*n);
x2 = cos(1/8*pi*n);
x3 = cos(2/8*pi*n);
x4 = cos(1*pi*n);
subplot(4,1,1), stem(n,x1,'filled'), axis([0,31,-1.5 1.5])
subplot(4,1,2), stem(n,x2,'filled'), axis([0,31,-1.5 1.5])
subplot(4,1,3), stem(n,x3,'filled'), axis([0,31,-1.5 1.5])
subplot(4,1,4), stem(n,x4,'filled'), axis([0,31,-1.5 1.5])
%plot -s 560,600
N = 32;
n = 0:N-1;
x5 = cos(2*pi*n);
x6 = cos(15/8*pi*n);
x7 = cos(14/8*pi*n);
x8 = cos(1*pi*n);
subplot(4,1,1), stem(n,x5,'filled'), axis([0,31,-1.5 1.5])
subplot(4,1,2), stem(n,x6,'filled'), axis([0,31,-1.5 1.5])
subplot(4,1,3), stem(n,x7,'filled'), axis([0,31,-1.5 1.5])
subplot(4,1,4), stem(n,x8,'filled'), axis([0,31,-1.5 1.5])
%plot -s 560,400
t = linspace(0,10*2*pi,100);
x = sin(t);
y = cos(t);
ts = linspace(0,10*2*pi,10);
xs = sin(ts);
ys = cos(ts);
tc = linspace(0,10*2*pi,100);
xc = sin(1/10*tc);
yc = cos(1/10*tc);
subplot(2,1,1), plot(t,x,'--'), hold on
plot(ts,xs,'o','markerfacecolor','r'),
plot(tc,xc,'r-'), hold off
title('sin(t)')
yticks([-1,0,1])
xlim([0,10*2*pi])
subplot(2,1,2), plot(t,y,'--'), hold on
plot(ts,ys,'o','markerfacecolor','red'),
plot(tc,yc,'r'), hold off
xlabel('sec'), title('cos(t)')
yticks([-1,0,1])
xlim([0,10*2*pi])
%plot -s 560,400
t = linspace(0,10*2*pi,100);
x = sin(t);
y = cos(t);
ts = linspace(0,10*2*pi,5);
xs = sin(ts);
ys = cos(ts);
tc = linspace(0,10*2*pi,100);
xc = sin(1/5*tc);
yc = cos(1/5*tc);
subplot(2,1,1), plot(t,x,'--'), hold on
plot(ts,xs,'o','markerfacecolor','r'),
plot(tc,xc,'r-'), hold off
title('sin(t)')
yticks([-1,0,1])
xlim([0,10*2*pi])
subplot(2,1,2), plot(t,y,'--'), hold on
plot(ts,ys,'o','markerfacecolor','red'),
plot(tc,yc,'r'), hold off
xlabel('sec'), title('cos(t)')
yticks([-1,0,1])
xlim([0,10*2*pi])
%%html
<center><iframe
width="560" height="315" src="https://www.youtube.com/embed/jHS9JGkEOmA?rel=0" frameborder="0" allowfullscreen>
</iframe></center>
Periodicity of Sinusoids
Harmonic Sinusoids
$$e^{j(\omega n + \phi)}$$%plot -s 560,420
N = 8;
k = 1;
w = 2*pi/N*k;
z1 = exp(1j*w);
n = 0:N-1;
z = (z1.^n).';
zplane(z)
title(['$z~{\rm in~the~complex~plane}$'],'interpreter','LaTeX','fontsize',12);
%plot -s 560,420
k = 3;
N = 8;
n = 0:N-1;
xp = exp(1j*2*pi/N*k*n);
x = exp(1j*2*pi/N*k*0);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*1);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*2);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*3);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*4);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*5);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*6);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 560,420
x = exp(1j*2*pi/N*k*7);
plot(real(xp),imag(xp),'o'), hold on
plot(real(x),imag(x),'o', 'MarkerFaceColor','b', 'MarkerEdgeColor','b'), hold off
grid on
axis equal; axis([-1.5, 1.5,-1.4 1.4])
%plot -s 800,600
N = 8;
n = 0:N-1;
for k = 0:N-1;
x = exp(1j*(2*pi/N)*k*n);
subplot(8,2,2*k+1)
stem(n,real(x),'b','filled');
xticks([])
ylabel(['k = ',num2str(k)],'fontsize',10);
axis([0, 7, -1, 1]);
subplot(8,2,2*k+2)
stem(n,imag(x),'r','filled');
xticks([])
axis([0, 7, -1, 1]);
end
subplot(821)
title(['${\rm Re}(e^{j \frac{2\pi}{8}kn}) = \cos(\frac{2\' ...
'pi}{8}kn)$'],'interpreter','LaTeX','fontsize',12);
subplot(822)
title(['${\rm Im}(e^{j \frac{2\pi}{8}kn}) = \sin(\frac{2\' ...
'pi}{8}kn)$'],'interpreter','LaTeX','fontsize',12);
subplot(8,2,15), xticks([0,1,2,3,4,5,6,7]), xlabel('n')
subplot(8,2,16), xticks([0,1,2,3,4,5,6,7]), xlabel('n')
%plot -s 900,400
N = 8;
n = 0:N-1;
for k = 0:N-1
D(:,k+1) = exp(1j*(2*pi/N)*k*n).';
end
subplot(121), imagesc(n,n,real(D)), colormap('jet'), axis square
xlabel('$k$','interpreter','LaTeX','fontsize',12);
ylabel('$n$','interpreter','LaTeX','fontsize',12);
title('${\rm Re}(e^{j\frac{2\pi}{N}kn})=\cos(\frac{2\pi}{N}kn)$',...
'interpreter','LaTeX','fontsize',12);
colorbar
subplot(122), imagesc(n,n,imag(D)), colormap('jet'), axis square
xlabel('$k$','interpreter','LaTeX','fontsize',12);
ylabel('$n$','interpreter','LaTeX','fontsize',12);
title('${\rm Im}(e^{j\frac{2\pi}{N}kn})=\sin(\frac{2\pi}{N}kn)$',...
'interpreter','LaTeX','fontsize',12);
colorbar
%%html
<center><iframe src="https://www.youtube.com/embed/vDulP6vTa9g?rel=0"
width="560" height="315" frameborder="0" allowfullscreen></iframe></center>
$$x[n]=\gamma^n e^{j\frac{2\pi}{N} n}$$
%% real and imag parts
r = 0.95;
N = 20;
n = 0:2*N-1;
x = (r.^n).*exp(1j*2*pi/N*n);
1) retangular form
%plot -s 560,400
subplot(2,1,1)
stem(n,real(x),'filled'), hold on
plot(n, [1;-1]*r.^n,'k--'), hold off
ylabel('Re')
subplot(2,1,2)
stem(n,imag(x),'filled'), hold on
plot(n, [1;-1]*r.^n,'k--'), hold off
ylabel('Im'), xlabel('n')
%plot -s 560,520
c = [0, 0.4470, 0.7410];
plot3(n,real(x),imag(x),'o','MarkerFaceColor',c,'MarkerEdgeColor',c), hold on
plot3(n,zeros(size(n)),zeros(size(n)),'k--'), hold off
xlabel('n'), ylabel('Re'), zlabel('Im')
grid on
ylim([-1,1])
zlim([-1,1])
view([20,30])
2) polar form
$$ \begin{align*} x[n] &=\gamma^n e^{j\frac{2\pi}{N} n}\\ &= \lvert x[n]\lvert \, e^{j\angle x[n]} \end{align*} $$%% polar coordinate
fig = polar(angle(x),abs(x),'o'); % theta in radian
set(fig,'MarkerFaceColor',[0, 0.4470, 0.7410],'MarkerEdgeColor',[0, 0.4470, 0.7410]);
%% polar coordinate
subplot(3,1,1)
stem(n,abs(x),'filled')
ylabel('|x[n]|','fontsize',12)
subplot(3,1,2)
stem(n,phase(x),'filled')
ylabel('\angle x[n] in phase','fontsize',12)
subplot(3,1,3)
stem(n,angle(x),'filled')
ylabel('\angle x[n] in angle','fontsize',12), xlabel('n')
% be careful with ' in MATLAB
a = [2 + 1j, 1 - 2j];
a'
a.'
Linear Combination = Matrix Multiplication
%plot -s 560,400
N = 32;
n = 0:N-1;
k = 1;
d1 = cos(2*pi/N*k*n)';
k = 2;
d2 = cos(2*pi/N*k*n)';
subplot(211)
stem(n,d1,'filled'), ylabel('d_1[n]'), axis tight
subplot(212)
stem(n,d2,'filled'), ylabel('d_2[n]'), axis tight
% Note: in Matlab, the operation ' performs complex conjugate transpose
innerproduct = d2'*d1
%plot -s 560,400
N = 32;
n = 0:N-1;
k = 1;
d1 = exp(1j*2*pi/N*k*n).';
k = 3;
d2 = exp(1j*2*pi/N*k*n).';
subplot(211)
stem(n,real(d1),'b','marker','none'); hold on, ylabel('d_1[n]')
stem(n,imag(d1),'r','marker','none'); hold off
title('Real part = Blue, Imaginary part = Red','fontsize',10)
subplot(212)
stem(n,real(d2),'b','marker','none'); hold on, ylabel('d_2[n]')
stem(n,imag(d2),'r','marker','none'); hold off
% Note: in Matlab, the operation ' performs complex conjugate transpose
innerproduct = d2'*d1
% to check two complex signals are orthonormal
N = 16;
n = 0:N-1;
k = 3;
s_3 = 1/sqrt(N)*exp(1j*2*pi/N*k*n).';
k = 5;
s_5 = 1/sqrt(N)*exp(1j*2*pi/N*k*n).';
% ': complex conjugate transpose
s_3'*s_5 % to see they are orthogonal
s_3'*s_3 % to see it is normalized
s_5'*s_5 % to see it is normalized
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')