Mục Lục
I. Project 1:CIRCULAR INDEXING
4
1.1:Circular Shift and Rotations
1.2:Circular Flip
1.3:Flipping and Shift Signals
II.Project 2:CIRCULAR CONVOLUTION
26
2.1:Function for Circular Convolution
2.2:More Examlies of Circular Convolution
2.3:Flipping and Shifting Signals
III.Procject 3:RELATION TO LINEAR CONVOLUTION
43
3.1:Study the conv Function
3.2:Convolution as a Matrix Operation
3.3:Circular Convolution via Time Aliasing
3.4:Circular Convolution via Periodic Extension
3.5:Zero Padding
3.6:Good Outputs versus Bad Outputs
IV:Project 5:HIGHT-SPEED CONVOLUTION
5.1:FFT conv Function
5.2:Crossover Point
Trang 1
66
5.3:Compare with FIR Filtering
V:Project 3:RESOLUTION
77
(Procject 3 này khác project 3 ở phần trước)
3.1:Definition of Resolution
3.2:Peak Finding
3.3:Measuring Resolution
***************************************
Một số hàm và M-file đã viết trong bài là:
1:
cflip.m
(hàm lật vòng)
2:
circonv.m
(hàm chập vòng sử dụng FFT)
3:
circonv1.m
(hàm chập vòng sử dụng định nghĩa)
4:
cirmatrix.m
(hàm tạo ma trận vòng)
5:
cirshift.m
(hàm dịch vòng)
6:
convmatrix.m (hàm tạo ma trận chập tuyến tính)
7:
Mod.m
8:
new_conv.m
(hàm tính modulo của 2 số)
(hàm chập tuyến tính sử dụng
kĩ thuật over-save)
9:
new_conv1.m
(hàm chập tuyến tính sử dụng
kĩ thuật over-add)
Trang 2
10: new_conv2.m
(hàm chập tuyến tính cho tín hiệu thực sử
dụng kĩ thuật over-save)
11: peak_finding.m (hàm tìm những đỉnh của tín hiệu)
12: periodic_conv.m (hàm chập vòng sử dụng conv)
13: puzzle.m
(M-file giải câu đố trong project 2)
14: resolution.m
(M-file tính điểm cho cửa sổ chữ nhật
theo ΔW)
15: resolution1.m
(hàm tính điểm và vẽ đồ thị điểm
theo ΔW cho các cửa sổ)
16: time_alias.m
(hàm tạo dãy tuần hoàn chu kì cho trước)
Trang 3
Sinh viên:Đỗ Văn Hưởng
MSSV:20081335
Đề 7:
Project 1:CIRCULAR INDEXING
EXERCISE 1.1:Circular Shifts and Rotations
A.
Biến đổi DFT của một dãy đã được dịch vòng chỉ cần nhân dãy gốc với véc tơ mũ
phức W =.
Ta có thể dung MATLAB để kiểm tra tính chất này.Ta sử dụng các tín hiệu vào là:
1.Tín hiệu vào là xung đơn vị:[n]
Biểu diễn trong MATLAB:(ta chỉ lấy mẫu trong khoảng [0,9]
Trang 4
>> clear
>> n=[0:9];
>> x=[n==0]
x=
1
0
0
0
0
0
0
0
0
0
>> stem(n,x)
>> title('Impulse signal')
>> xlabel('n')
>> ylabel('x[n]')
>> %gia su l=2
N=10;
l=2;
W=exp(-j*2*pi/N*l*n);
>> %su dung ham dich vong cirshift
a=cirshift(x,l);
>> fft(a)
ans =
Columns 1 through 7
1.0000
0.3090 - 0.9511i -0.8090 - 0.5878i -0.8090 + 0.5878i
+ 0.9511i 1.0000
0.3090 - 0.9511i
Columns 8 through 10
-0.8090 - 0.5878i -0.8090 + 0.5878i 0.3090 + 0.9511i
>> fft(x).*W
Trang 5
0.3090
ans =
Columns 1 through 7
1.0000
0.3090 - 0.9511i -0.8090 - 0.5878i
+ 0.9511i 1.0000 0.3090 - 0.9511i
-0.8090 + 0.5878i
Columns 8 through 10
-0.8090 - 0.5878i -0.8090 + 0.5878i 0.3090 + 0.9511i
Ta nhận thấy sư giống nhau hoàn toàn giữa fft(a) và fft(x).*W
Đúng như trong nhận xét.
2.Tín hiệu vào là xung (pulse)
clear
Trang 6
0.3090
n=0:9;
x=[n<=5]
x=
1
1
1
1
1
1
0
0
0
0
>> stem(n,x);
>> title('pulse signal');
>> xlabel('n')
ylabel('x[n]')
>> N=10;
l=2;
W=exp(-j*2*pi/N*l*n);
%su dung ham dich vong cirshift
>> a=cirshift(x,l);
>> fft(a)
ans =
Columns 1 through 7
6.0000
0.9511i
-2.9271 - 0.9511i -0.8090 - 0.5878i 0.4271 + 0.5878i 0.3090 +
0
0.3090 - 0.9511i
Columns 8 through 10
0.4271 - 0.5878i -0.8090 + 0.5878i -2.9271 + 0.9511i
>> fft(x).*W
ans =
Columns 1 through 7
Trang 7
6.0000
0.9511i
-2.9271 - 0.9511i -0.8090 - 0.5878i 0.4271 + 0.5878i 0.3090 +
0
0.3090 - 0.9511i
Columns 8 through 10
0.4271 - 0.5878i -0.8090 + 0.5878i -2.9271 + 0.9511i
Ta nhận thấy sư giống nhau hoàn toàn giữa fft(a) và fft(x).*W
Đúng như trong nhận xét.
3.Tín hiệu vào là xung hình sin
clear
n=0:9;
x=sin(n)
Trang 8
x=
0
0.4121
0.8415
0.9093
0.1411 -0.7568 -0.9589 -0.2794
0.6570
0.9894
>> stem(n,x);
>> title('Sinusoids signal');
>> xlabel('n');
>> ylabel('x[n]');
>> %gia su l=2
N=10;
l=2;
%dịch phải 2
W=exp(-j*2*pi/N*l*n); %vector mũ phức
%su dung ham dich vong cirshift
a=cirshift(x,l);
>> fft(a)
ans =
Columns 1 through 7
1.9552
1.5397 - 2.8134i 1.8290 + 2.7114i 0.6960 - 0.1292i 0.0195 0.3233i -0.2303
0.0195 + 0.3233i
Columns 8 through 10
0.6960 + 0.1292i 1.8290 - 2.7114i 1.5397 + 2.8134i
>> fft(x).*W
ans =
Columns 1 through 7
Trang 9
1.9552
1.5397 - 2.8134i 1.8290 + 2.7114i 0.6960 - 0.1292i 0.0195 0.3233i -0.2303 - 0.0000i 0.0195 + 0.3233i
Columns 8 through 10
0.6960 + 0.1292i 1.8290 - 2.7114i 1.5397 + 2.8134i
Ta nhận thấy sư giống nhau hoàn toàn giữa fft(a) và fft(x).*W
Đúng như trong nhận xét.
Ngoài ra nếu k=N/2 thì đây là 1 trường hợp đặc biệt.(ví dụ N=16 và k=8).Khi đó
Ta có W ==exp(-j*π )=-1
Chính vì vậy DFT của tín hiệu mới chỉ ngược về dấu so với tín hiệu gốc.
B. viết hàm tính modul (function Mod)
%Đầu vào là 2 số a,b
%Đầu ra là modulo c của chúng ( 0≤c
function c=Mod(a,b)
if a>=0 & a
c=a;
elseif a<0
c=Mod(a+b,b);
%Gọi đệ quy hàm Mod
elseif a>=b
c=Mod(a-b,b);
%Gọi đệ quy hàm Mod
end
Ta có thể kiểm tra hàm trên MATLAB
Ví dụ:
clear
>> Mod(-5,7)
ans =
2
C. viết hàm dịch vòng(function cirshift)
Trang 10
%Đầu vào hàm là tín hiệu b và số vị trí thay đổi l.Ta mặc định là dịch phải.
%Đầu ra là tín hiệu a đã được dịch.
function a=cirshift(b,l)
m=length(b);
x=[0:m-1];
for n=1:m
c(n)=Mod(x(n)-l,m)+1;
a=b(c);
end
Ta có thể kiểm tra hàm trên MATLAB
Ví dụ:
Clear
a=1:6
a=
1
2
3
4
5
6
2
3
4
6
1
2
>> cirshift(a,2)
ans =
5
6
1
>> cirshift(a,-2)
ans =
3
4
5
D.
Lúc đầu ta có dãy a=[0 1 2 3 4 5 6 7]
Ta có thể dùng hàm cirshift() để đưa về dãy [4 5 6 7 0 1 2 3 ]
>> a=0:7
a=
Trang 11
0
1
2
3
4
5
6
7
7
0
1
2
3
>> cirshift(a,4)
ans =
4
5
6
Ngoài ra ta cũng có thể không dùng đến cirshift() bằng cách dùng fft() trong
MATLAB.Ta dùng tính chất ở phần đầu của phép dịch vòng.Đầu tiên ta tính DFT
của dãy gốc.Nhân dãy này với vector mũ phức W.Sau đó dùng phép biến đổi
DFT ngược ta được dãy cần tìm.
Phép biến đổi DFT ngược: x[n]=
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear
>> n=0:7;
>> N=8;
>> x=[0 1 2 3 4 5 6 7 ]
x=
0
1
>> l=4;
2
3
4
5
6
7
% số vị trí thay đổi
>> W=exp(-j*2*pi/N*l*n); %vector mũ phức
>> X=fft(x).*W;
>> k=0:7;
>> for i=n+1
a(i)=1/N*sum(X.*exp(j*2*pi/N*k*n(i)));
end;
>> % dua ra day can tim
Trang 12
>> a
a=
Columns 1 through 7
4.0000 + 0.0000i 5.0000 + 0.0000i 6.0000 + 0.0000i 7.0000
1.0000 + 0.0000i 2.0000 - 0.0000i
0
Column 8
3.0000 + 0.0000i
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Ta có thể thử lại với trường hợp dãy cần đưa ra là [2 3 4 5 6 7 0 1]
Ta chỉ cần thay l=-2 là được;
clear
>> n=0:7;
>> N=8;
>> x=[0 1 2 3 4 5 6 7 ]
x=
0
1
>> l=-2;
2
3
4
5
6
7
% số vị trí thay đổi
>> W=exp(-j*2*pi/N*l*n); %vector mũ phức
>> X=fft(x).*W;
>> k=0:7;
>> for i=n+1
a(i)=1/N*sum(X.*exp(j*2*pi/N*k*n(i)));
end;
Trang 13
>> % dua ra day can tim
>> a
a=
Columns 1 through 7
2.0000 + 0.0000i 3.0000 + 0.0000i 4.0000
0.0000i 7.0000 - 0.0000i -0.0000 + 0.0000i
5.0000 + 0.0000i 6.0000 -
Column 8
1.0
+ 0.0000i
EXERCISE 1.2:Circular Flip
Viết hàm lật vòng (circular flip).ta đặt tên hàm là “cflip()”.Hàm có đầu vào là một
dãy số và đầu ra là một dãy đã được lật vòng.
%Đầu vào là dãy A
%Đầu ra la dãy B đã được lật vòng.
function B=cflip(A)
m=length(A);
for n=1:m
k=Mod(-(n-1),m)+1;
B(n)=A(k);
End
Ta có thể kiểm tra hàm trên bằng một vài ví dụ:
%%%%%%%%%%%%%%%%%
clear
>> cflip([0:1:7])
ans =
0
7
6
5
4
3
2
1
cflip([ 3 4 5 6 7 8 9 10])
Trang 14
ans =
10
9
8
7
6
5
4
cflip([ 1 3 7 2 3 6 9 8 11 2])
ans =
1 2
11
8
9
6
3
2
7
3
EXERCISE 1.3: Flipping and Singnals
A:
1.
Khởi tạo dãy x[n]=2n+3
Ta bắt đầu với dãy x[n]=2n+3 với n=0..10
Khởi tạo dãy này trong MATLAB như sau:
clear
>> n=0:10;
>> x=2*n+3
x=
3 5 7
2.
9
11
13
15
17
19
21
23
Vẽ x[(l-2)mod 11] với l=0,1..10
l=0:10;
% sử dụng hàm lật vòng
>> h=cirshift(x,2)
h=
21 23 3 5 7 9
>> subplot(211);
>> plot(n,x);
>> title('x[n]=2n+3');
>> xlabel('n');
>> ylabel('x[n]');
>> subplot(212);
>> plot(l,h);
>> title('x[(l-2)mod 11]');
11
13
15
Trang 15
17
19
>> xlabel('l');
>> ylabel('h[l]');
Kết quả đưa ra trong MATLAB như sau:
3.Vẽ x[(l+3)mod 11] với l=0,1..10
clear
n=0:10;
x=2*n+3
x=
3 5 7 9 11 13 15 17 19 21 23
>> l=0:10;
>> h=cirshift(x,-3)
h=
9 11 13 15 17 19 21 23 3 5 7
Trang 16
>> subplot(211);
plot(n,x);
>> title('x[n]=2n+3');
xlabel('n');
ylabel('x[n]');
subplot(212);
>> plot(l,h);
>> title('x[(l+3)mod 11]');
>> xlabel('l');
>> ylabel('h[l]');
Kết quả MATLAB đưa ra như sau:
4.Vẽ x[(4-l)mod 11] với l=0,1..10
clear
n=0:10;
Trang 17
x=2*n+3
x=
3
5
7
9
11
13
15
17
19
21
23
23
21
19
17
15
13
>> l=0:10;
% ta lật vòng trước
>> a=cflip(x);
% sau đó mới dịch vòng
>> h=cirshift(a,4)
h=
11
9
7
5
3
>> subplot(211);
plot(n,x);
title('x[n]=2n+3');
xlabel('n');
ylabel('x[n]');
subplot(212);
plot(l,h);
>> title('x[(4-l)mod 11]');
>> xlabel('l');
>> ylabel('h[l]');
Kết quả MATLAB đưa ra như sau:
Trang 18
Đối với bài này ta lên lật vòng trước rồi sau đó mới
dịch vòng.
5.Vẽ x[(-l-5)mod 11] với l=0,1..10
>> clear
n=0:10;
x=2*n+3
x=
3
5
7
9
11
13
15
17
19
Trang 19
21
23
>> l=0:10;
% ta lật vòng trước
>> a=cflip(x);
%sau đó mới dịch vòng -5
>> h=cirshift(a,-5)
h=
15 13 11 9 7 5
>> subplot(211);
plot(n,x);
title('x[n]=2n+3');
xlabel('n');
ylabel('x[n]');
subplot(212);
plot(l,h);
>> title('x[(-l-5)mod 11]');
>> xlabel('l');
>> ylabel('h[l]');
>>
3
23
21
19
17
Đối với bài này ta phải lật vòng trước sau đó mới dịch vòng -5;
Kết quả MATLAB đưa ra như sau:
Trang 20
B:
Khởi tạo tín hiệu x[n]=(0,87)^n
Trong bài này ta chỉ xoay chỉ số của tín hiệu.
Câu lệnh trong MATLAB như sau:
clear;
n=0:12;
nn=0:12;
x=(0.87).^n
Trang 21
x=
Columns 1 through 12
1.0000 0.8700 0.7569 0.6585
0.3282 0.2855 0.2484 0.2161
0.5729
Column 13
0.1880
>> subplot(211);
stem(n,x);
title('x[n]=(0.87)^n');
xlabel('n');
ylabel('x[n]');
l=cirshift(n,4);
subplot(212);
>> stem(n,(0.87).^l);
>> title('y[n]=x[(n-4)mod 13]');
>> xlabel('n');
>> ylabel('y[n]');
Kết quả được MATLAB đưa ra như sau:
Trang 22
0.4984
0.4336
0.3773
C:
Ta thử lại với z[n]=x[(2n+3)mod 13]
Dòng lệnh được viết trên MATLAB như sau:
clear;
n=0:12;
nn=0:12;
x=(0.87).^n
Trang 23
x=
1.0000 0.8700 0.7569 0.6585 0.5729
0.3282 0.2855 0.2484 0.2161 0.1880
>> subplot(211);
stem(n,x);
title('x[n]=(0.87)^n');
xlabel('n');
ylabel('x[n]');
>> l=mod(2*n+3,13);
>> subplot(212);
>> stem(n,0.87.^l);
>> title('z[n]=x[(2n+3)mod 13]');
>> xlabel('n');
>> ylabel('z[n]');
>>
Kết quả được đưa ra trên MALAB như sau:
Trang 24
0.4984
0.4336
0.3773
Trang 25