Tải bản đầy đủ (.docx) (31 trang)

Bài tập lớn : XỬ LÝ SỐ TÍN HIỆU

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (509.07 KB, 31 trang )

Họ Tên
STT
MSSV
Lớp

:
:
:
:

Nguyễn Kim Thành
369
20083484
Kỹ Thuật Đo – K53

Bài tập lớn : XỬ LÝ SỐ TÍN HIỆU
Project 5: HIGH-SPEED CONVOLUTION
EXERCISE 5.1:FFT conv Function
1.Viết lại hàm conv sử dụng thuật toán overlap-save.
Ta đặt tên hàm mới này thành new_conv.Hàm này sử dụng kĩ thuật overlap-save.Chia tín hiệu dài thành
nhiều khối nhỏ.Sử dung fft để tính đầu ra .chỉ lấy L điểm cuối của mỗi khối.Đoạn chương trình viết trên
MATLAB như sau:
%Đầu vào là 2 tín hiệu cần nhân chập và chiều dài của FFT ta sẽ sử dụng
%Đầu ra là tín hiệu y là chập tuyến tính cần tìm
function y=new_conv(x,h,N)
nx=length(x);
nh=length(h);
%%Chọn tín hiệu dài hơn để chia.
if nx>nh
b=h;nb=nh;
a=[zeros(1,nh-1) x];Thêm không điểm vào đầu


na=nx+nh-1;
else
b=x;nb=nx;
a=[zeros(1,nx-1) h];Thêm không điểm vào đầu
na=nh+nx-1;
end;
if nargin<3 %%Nếu đầu vào không có N thì tự động tạo N
N=nb;
else
if N%N phải >nb
N=nb;
end;
end;
N = 2.^(ceil(log(N)/log(2))); %Đưa N về lũy thừa của 2
L = N- nb + 1;
B=fft(b,N);
y = zeros(1,na);
istart = 1;


while istart <= na
iend = min(istart+N-1,na);
if (iend - istart) == 0
A = a(istart);
else
A= fft(a(istart:iend),N);
end
Y = ifft(A.*B);
ystart=istart;

yend = min(na,istart+L-1);
y(ystart:yend) = Y(nb:nb+yend-ystart);%chỉ lấy những điểm cuối
istart = istart + L;
end
%%%%%%%%%%%%%%%%%%
Ta cũng có thể dung kĩ thuật overlap-add để tính nhân châp.Kĩ thuât này sẽ lấy L điểm đầu.
%Đầu vào là 2 tín hiệu cần nhân chập và chiều dài của FFT ta sẽ sử dụng
%Đầu ra là tín hiệu y là chập tuyến tính cần tìm
function y=new_conv1(x,h,N)
nx=length(x);
nh=length(h);
%Xác định xem vector nào dài hơn
if nx>nh
b=h;nb=nh;
a=x;
na=nx;
else
b=x;nb=nx;
a=h;
na=nh;
end;
%% Se phan doan a.
if nargin<3 %Nếu đầu vào không có N thì tự động tạo N
N=nb;
else
if N%Nếu NN=nb;
end;
end;

N = 2.^(ceil(log(N)/log(2))); % Đưa N thành lũy thừa của 2
L = N- nb + 1;
%Chiều dài của khối chập
B=fft(b,N);
%Chỉ tính fft của b 1 lần
y = zeros(1,na+nb-1);
istart = 1;
while istart <= na
iend = min(istart+L-1,na);
if (iend - istart) == 0


A = a(istart);
else
A= fft(a(istart:iend),N);
end
Y = ifft(A.*B);
yend = min(na+nb-1,istart+N-1);
y(istart:yend) = y(istart:yend) + Y(1:(yend-istart+1));
istart = istart + L;
end
%%%%%%%%%%%%%
Ta kiểm tra hàm trên với 2 tín hiệu sau:
%%%%%%%%%
clear
>> a=1:6;
>> b=3:12;
>> new_conv(a,b)
ans =
Columns 1 through 14

3.0000 10.0000 22.0000 40.0000 65.0000 98.0000 119.0000 140.0000 161.0000 182.0000
190.0000 184.0000 163.0000 126.0000
Column 15
72.0000
>> conv(a,b)
ans =
3 10 22 40 65 98 119 140 161 182 190 184 163 126 72
%%Kết quả hài hàm trên giống nhau.
EXERCISE 5.2:Crossover Point
A,B,C.
Ta khởi tạo 2 tín hiệu ngẫu nhiên có chiều dài biến thiên trong khoảng từ 80 đến 800.Khoảng này
có thể thay đổi tùy theo tốc độ của máy tính.Chương trình thử nghiệm đo tốc độ của hàm new_conv ta
vừa viết với hàm conv của MATLAB như sau:
for i=80:800
x=1.8e+20*randn(1,i)+7*j; % tạo tín hiệu ngẫu nhiên x
y=1.8e+20*randn(1,i)+8*j;

% Tạo tín hiệu ngẫu nhiên y

tic;conv(x,y);t1(i-79)=toc;

%Tính thời gian của hàm conv

tic;new_conv(x,y);t2(i-79)=toc; %Tính thời gian của hàm new_ conv
end;


D.Vẽ đồ thị thời gian thự hiện 2 hàm để xác định lúc nào thì hàm ta mới viết tỏ ra hiệu quả
n=80:800;
>> plot(n,10000*t1,n,10000*t2);


Nhìn trên đồ thị ta thấy 2 đồ thị cắt nhau tại những điểm là lũy thừa của 2(các điểm cắt là tại
N=128,256,512.Khi chiều dài của tín hiệu gần đến lũy thừa của 2 thì thời gian tính toán tăng đột
ngột.Nhưng khi đến lũy thừa của 2 thì thời gian tinh toán giảm đến mưc thấp nhất.Vì vậy tại những độ dài
nhỏ hàm conv thì nhanh nhưng với những độ dài lớn thì hàm new_conv tỏ ra nhanh hơn rõ rệt.
E.Kiểm tra với đầu vào là tín hiệu thực.
Nếu đầu vào là tín hiệu thực thì DFT của chúng là một tín hiệu liên hợp đối xứng .Chính vì vậy để tính
IFFT nhanh hơn ta có thể mặc định tín hiệu vào là ‘symmetric’.Một chỉnh sửa nhỏ của hàm new_conv ta
được 1 hàm mới .Đặt tên hàm này là new_conv2.
Đoạn code trên MATLAB như sau:
%%%%%%%%%%%%%%
%Đầu vào là 2 tín hiệu cần nhân chập và chiều dài của FFT ta sẽ sử dụng
%Đầu ra là tín hiệu y là chập tuyến tính cần tìm
function y=new_conv2(x,h,N)
nx=length(x);
nh=length(h);
if nx>nh
b=h;nb=nh;
a=[zeros(1,nh-1) x];
na=nx+nh-1;
else
b=x;nb=nx;
a=[zeros(1,nx-1) h];
na=nh+nx-1;
end;
if nargin<3


N=nb;
else

if NN=nb;
end;
end;
N = 2.^(ceil(log(N)/log(2)));
L = N- nb + 1;
B=fft(b,N);
y = zeros(1,na);
istart = 1;
while istart <= na
iend = min(istart+N-1,na);
if (iend - istart) == 0
A = a(istart);
else
A= fft(a(istart:iend),N);
end
Y = ifft(A.*B,'symmetric'); %Mặc định input là dạng symmetric
ystart=istart;
yend = min(na,istart+L-1);
y(ystart:yend) = Y(nb:nb+yend-ystart);
istart = istart + L;
end
%%%%%%%%%%%%%
Ta thực nghiệm bằng 1 ví dụ đơn giản để thấy sức mạnh của hàm mới này:
%%%%%%%%%%%%
clear;
>> a=1:80000;
>> tic;conv(a,a);t1=toc
t1 =
32.7045

>> tic;new_conv(a,a);t2=toc
t2 =
0.1343
>> tic;new_conv2(a,a);t3=toc
T3 =
0.1099
%%Nhận thấy hàm new_conv2 nhanh hơn hàm conv khoảng 300 lần!


EXERCISE 5.3:Compare with FIR Filtering
A,B:
Khởi tạo 2 tín hiệu h của bộ lọc và x của đầu vào.Để công bằng chúng ta nên khởi tạo 2 tín hiêu này
là phức và ngẫu nhiên.
%%%%%%%%%%
clear
Lh=40;
Lx=200000;
h=rand(1,Lh)+i*rand(1,Lh);
x=rand(1,Lx)+i*rand(1,Lx);
%%%%%%%%%%%
C:Sử dụng hàm new_conv2 để tính chập
Ta đươc kết quả trên MATLAB như sau:
%%%%%%%%%%%%%%%%%%%
clear
Lh=40;
Lh=200000;
h=rand(1,Lh)+i*rand(1,Lh);
x=rand(1,Lx)+i*rand(1,Lx);
N=64;i=1;
while N<400000

n(i)=N;N
tic;new_conv2(x,h,N);t=toc
t1(i)=t;
N=2^(log2(N)+1);
i=i+1;
end
N=
64
t=
0.1321
N=
128
t=
0.0496
N=
256
t=
0.0345
N=
512
t=
0.0276
N=


1024
t=
0.0340
N=
2048

t=
0.0405
N=
4096
t=
0.0358
N=
8192
t=
0.0328
N=
16384
t=
0.0435
N=
32768
t=
0.0479
N=
65536
t=
0.0675
N=
131072
t=
0.0811
%%%%
Nhận thấy với N càng lớn thì thời gian tính càng nhanh,nhưng chỉ đến N=1024 thì tốc độ lại chậm
đi.Theo kết quả tính phía trên thì với N=256 thì phép chập là nhanh nhất.Nói chung tốt nhất chọn độ dài
của khối chia L là vào khoảng từ 5 đến 10 lần chiều dài của bộ lọc

D.Vẽ 2 hàm thời gian thực hiện để so sánh tốc độ của chúng.
Ta sẽ viết tiếp đoạn chương trình đã viết ở phần C.
%%%%%%%%%


t1 =
0.1321 0.0496 0.0345 0.0276 0.0340 0.0405 0.0358
0.0811
tic;conv(x,h);t=toc
t=
0.0906
t2=t*ones(1,12);
>> n=log2(n)
n=
6 7 8 9 10 11 12 13 14 15 16 17
>> plot(n,t1,n,t2)
>> title('thoi gian thuc hien cua new_conv2 va conv');
>> xlabel('log2(N)');
>> ylabel('t');
>>

0.0328

0.0435

0.0479

0.0675

E.Nói chung với những bộ lọc có độ dài rất nhỏ so với độ dài của tín hiệu vào thì nhận xét trên

vẫn đúng.Với những bộ lọc có độ dài lớn so với đầu vào thì nhận xét trên không còn đúng.
clear
Lh=50000;
Lx=200000;
h=rand(1,Lh)+i*rand(1,Lh);
x=rand(1,Lx)+i*rand(1,Lx);
N=2^16;i=1;
while N<400000


n(i)=N;N
tic;new_conv2(x,h,N);t=toc
t1(i)=t;
N=2^(log2(N)+1);
i=i+1;
end
N=
65536
t=
0.2616
N=
131072
t=
0.1374
N=
262144
t=
0.2411
>>
------------------------------------------------------------


Project 3: RESOLUTION
EXERCISE 3.1:Definition of Resolution
A.Khởi tạo và vẽ phổ biên độ với tần số thay đổi
Ta viết 1 vòng lặp để thay đổi tần số và quan sát phổ pha.Chương trình trên MATLAB như sau:
%%%%%%%%%%
clear;
A1=10;
A2=10;
n=0:63;
L=64;
q1=2*pi*rand(1,1);
q2=q1
q2 =
3.8129
>> w1=1;
>> w2=1;
>> while (w2>0)
w2=input('Nhap w2=');
x1=A1*exp(j*(w1*n+q1));


x2=A2*exp(j*(w2*n+q2));
y=x1+x2;
plot(n,abs(fft(y,64)));
title('pho bien do cua y[n]');
xlabel('n');
ylabel('A[n]');
end
Nhap w2=2



Nhap w2=1.5

Nhap w2=1.3


Nhap w2=1.2


Nhap w2=1.1

%%%%%%%%%
Ta nhận thấy khi ΔW giảm dần từ 1 xuống 0.1 thì 2 đỉnh dần tiến về nhau.khi ΔW=0.1 thì gần như ta chỉ
quan sát thấy 1 đỉnh.
B.Thử lại với FFT 128 và FFT 256
clear;
%%Trường hợp FFT 128
A1=10;
A2=10;
n=0:63;
L=64;
n=0:63;
q1=3.8129;
q2=q1;
w1=1;
w2=1;
while (w2>0)
w2=input('Nhap w2=');
x1=A1*exp(j*(w1*n+q1));

x2=A2*exp(j*(w2*n+q2));
y=x1+x2;
plot(0:127,abs(fft(y,128)));
title('pho bien do cua y[n]');


xlabel('n');
ylabel('A[n]');
end
%%%%%%%%%%%%%
Kết quả như sau:
Nhap w2=1.5

Nhap w2=1.3


Nhap w2=1.1


Nhap w2=1.08

Nhap w2=1.05


Nhận thấy kết quả vẫn giống như phần A nhưng ΔW nhỏ nhất để 2 đỉnh hợp lại thành 1 giảm xuống còn
ΔW=0.05
%%%
clear;
%%Trường hợp FFT 256
A1=10;

A2=10;
n=0:63;
L=64;
n=0:63;
q1=3.8129;
q2=q1;
w1=1;
w2=1;
while (w2>0)
w2=input('Nhap w2=');
x1=A1*exp(j*(w1*n+q1));
x2=A2*exp(j*(w2*n+q2));
y=x1+x2;
plot(0:255,abs(fft(y,256)));
title('pho bien do cua y[n]');
xlabel('n');
ylabel('A[n]');
end
%%%%%%%
%%Kết quả trên MATLAB như sau:
Nhap w2=1.5


Nhap w2=1.3

Nhap w2=1.1


Nhap w2=1.04



Nhận thấy kết quả vẫn giống như phần A nhưng ΔW nhỏ nhất để 2 đỉnh hợp lại thành 1 giảm xuống còn
ΔW=0.04
Tóm lại để phân biệt được các đỉnh thì ΔW ≥ 2π /L.

EXERCISE 3.2:Peak Finding
A,B.Viết hàm Peak Finding
Hàm trên được viết trên MATLAB như sau:
%%%%%%%%%%
function [a,len]=peak_finding(y,n)
x=diff(abs(y))./diff(n);
k=1;
for i=1:length(n)-2
if(x(i)>0&x(i+1)<0&y(i+1)>=max(abs(y))/2)
a(k)=n(i+1);k=k+1;
end
end
if(k==1)
a=[];
end;
if(nargout<2)
return;
else
len=length(a);
end
%%%%%%%%%%
C.Kiểm tra hàm trên với cửa sổ chữ nhật
Chương trình trên MATLAB như sau:
Ta thử với tín hiệu hình sin y[n]
%%%%%%%%%%%%%%%%%%%

clear;
n=0:200;
y=20*cos(3*n+4)+20*cos(3.5*n+4);
W=[ones(1,64) zeros(1,201-64)];
>> y.*W;


>> y=ans(1:64)
y=
Columns 1 through 14
-26.1457 22.0108 -16.6929 11.0505 -5.9469
-11.6385 17.0760 -21.9823 25.5232

2.1383 -0.1752

0.3312 -2.5677

6.5392

Columns 15 through 28
-27.0092 25.9882 -22.3081 16.1420 -7.9718 -1.4667 11.2715 -20.4830 28.2001 -33.6896
36.4741 -36.3885 33.5970 -28.5695
Columns 29 through 42
22.0192 -14.8106 7.8491 -1.9662 -2.1855
-13.8443 15.5674 -15.1135

4.2128 -4.0296

1.8643


1.7736 -6.1625 10.4659

Columns 43 through 56
12.2413 -7.0268 -0.1404 8.6015 -17.5069 25.9199 -32.9315 37.7732 -39.9115 39.1150
-35.4821 29.4292 -21.6382 12.9721
Columns 57 through 64
-4.3673 -3.2817

9.2320 -12.9823 14.3315 -13.3987 10.6022 -6.6002

>> Y=fft(y);
>> plot(0:63,abs(Y));

>> a=peak_finding(abs(Y),0:63)
a=
28

30 34

36

%%%%%%%%%%%%%


D.Kiểm tra với hàm cửa sổ Hamming
clear
N=64;
n=0:63;
W=0.54+0.46*cos(2*pi*n/(N-1));
y=20*exp(j*(2*n+3))+20*exp(j*(2.27*n+3));

y1=y.*W;
Y1=fft(y1);
plot(n,abs(Y1))
>> title('cua so Hamming');
>> xlabel('n');
>> ylabel('A');
>> a=peak_finding(abs(Y1),n);
>> a


a=
20 23

EXERCISE 3.3:Measure Resolution
A.Hàm peak_finding ta vừa viết có thể trả về số lượng peak của tín hiệu.Ta có thể kiểm tra nó:
%%%%%%%%%%%
clear
N=64;
n=0:63;
W=0.54+0.46*cos(2*pi*n/(N-1));


y=20*exp(j*(2*n+3))+20*exp(j*(2.27*n+3));
y1=y.*W;
Y1=fft(y1);
plot(n,abs(Y1))
>> title('cua so Hamming');
>> xlabel('n');
>> ylabel('A');
>> [a,l]=peak_finding(abs(Y1),n);

>> a
a=
20 23
>>l
l=
2
%%%%%%%%
B.Viết 1 script khởi tạo tín hiệu và tính toán
Chương trình viết trên MATLAB như sau:
%%%%%%%%%%%%%
clear
A1=10;
A2=10;
n=0:63;
L=64;
q1=3.8;
q2=q1;
delta=0;
while delta<4*pi/L
delta= input('Nhap delta=');
score=0;
for i=1:10
w1=rand(1,1);
w2=w1+delta;
x1=A1*exp(j*(w1*n+q1));
x2=A2*exp(j*(w2*n+q2));
y=x1+x2;
Y=fft(y);



[a,l]=peak_finding(abs(Y),n);
if (l==2)
score=score+1;
end
end
fprintf('delta=%g Score=%g phantram\n',delta,score/10*100);
end
%%%%%%%%%
Chạy đoạn script trên với Window Command ta được kết quả sau:
%%%%%%%%%%
clear
>> resolution
Nhap delta=0.19
delta=0.19 Score=100 phantram
Nhap delta=0.17
delta=0.17 Score=80 phantram
Nhap delta=0.16
delta=0.16 Score=70 phantram
Nhap delta=0.13
delta=0.13 Score=50 phantram
Nhap delta=0.12
delta=0.12 Score=50 phantram
Nhap delta=0.1
delta=0.1 Score=30 phantram
Nhap delta=0.09
delta=0.09 Score=10 phantram
Nhap delta=0.08
delta=0.08 Score=10 phantram
Nhap delta=0.06
delta=0.06 Score=0 phantram

Nhap delta=0.05
delta=0.05 Score=0 phantram
Nhap delta=0.04
delta=0.04 Score=0 phantram
Nhap delta=0.03
delta=0.03 Score=0 phantram
Nhap delta=0.2
delta=0.2 Score=100 phantram
>>
%%%%%%%%%%%%
C.
Nhận thấy khi ΔW tiến gần đến 4π /L=0.19 thì score =100%
Khi ΔW<2π /L=0.09 thì score tiến về 0%.
Ta có thể chỉnh sửa script trên để không những tính điểm theo ΔW mà còn theo độ dài L của FFT(Tốt
nhất là lấy L là lũy thừa của 2).Sau đó script này có thể vẽ đồ thị của score phụ thuộ ΔW và L.Đoạn script
được sửa lại như sau:
%%%%%%%%%%
function resolution1(s)
if (~strcmp(s,'chunhat'))&(~strcmp(s,'hamming'))&(~strcmp(s,'hanning'))


×