Biến đổi fourier rời rạc part 3 doc

10 272 0
Biến đổi fourier rời rạc part 3 doc

Đang tải... (xem toàn văn)

Thông tin tài liệu

95 /* Taking FFT. */ FFT(xr, xi, wr, wi, m, N); printf("Enter file name for storing FFT output >"); scanf("%s",file_name); fptr=fopen(file_name,"w"); for(i=0;i<N;i++) fprintf(fptr," %e %e",xr[i], xi[i]); fclose(fptr); } void bit_reversal(unsigned int *L, int m, int N) /* Routine for generating LUT for bit reversal. Note: N=(2 to the power of m). LUT will reside in LI]*/ { unsigned int MASK,C,A,j,k,i; for(k=0;k<N;k++) { MASK=1; C=0; for(i=0,j=m-1;i<m;i++,j ) { A=(k&MASK)>>i; A<<=j ; C|=A; MASK=MASK<<1; } L[k]=C; } } void WTS(float *wr, float *wi, int N, int sign) /* Generating LUT for twiddle factors. Note: sign=-1 for FFT, and sign=1 for IFFT */ { int n2,i ; 96 float theta; n2=(N>>1)-1; /* Generate look-up tables for twiddle factor. */ theta=2.0*pi/((float)N); for(i=0;i<n2;i++) { wr[i]=(float)cos((double)((i+1)*theta)); wi[i]=(float)sin((double)((i+1)*theta)); if(sign==(int)(-1)); wi[i]=-wi[i]; } } /********************************************/ void FFT (float *xr, float *xi, float *wr, float *wi, int m, int N) { /* FFT algorithm, Decimation-in-time algorithm. Note: 1. N=2 to the power of m. 2. The input arrays are assumed to be rearranged in bit-reverse order. You will need to use routine "bitreversal" for that purpose. 3. The twiddle factors are assumed to be stored in LUT's wr[I and wi[j. You will need to use routine LUT for calculating and storing twiddle factors.*/ int ip,k,kk,l,incr,iter,j,i; float Tr,Ti; ip=1; kk=(N>>1); incr=2 ; for(iter=0; iter<m; iter++) 97 { for(j=0; j<N; j+=incr) { i=j+ip; Tr=xr[i]; Ti=xi[i]; xr[i]=xr[j]-Tr; xi[i]=xi[j]-Ti; xr[j]=xr[j]+Tr; xi[j]=xi[j]+Ti; } if(iter!=0) { for(k=1; k<ip; k++) { l=k*kk-1 ; for(j=k; j<N; j+=incr) { i=j+ip ; Tr=xr[i]*wr[l]-xi[i]*wi[l]; Ti=xr[i]*wi[l]+xi[i]*wr[l]; xr[i]=xr[j]-Tr; xi[i]=xi[j]-Ti; xr[j]=xr[j]+Tr; xi[j]=xi[j]+Ti; } } } kk>>=1; ip<<=1; incr<<=1; } } 98 Chú ý rằng trong chơng trình 6.1 chúng ta giả thiết là dữ liệu đợc lu nh dãy của các ký tự không dấu. Nếu bạn muốn xử lý trên một số dấu phẩy động bạn cần thay đổi các câu lệnh mở và đọc dữ liệu trong file dữ liệu. Chơng trình này cũng cho phép lựa chọn FFT hoặc IFFT. Cho FFT, chơng trình con "WTS( ) " tính toán và lu các hệ số dịch xoay trong một LUT đợc gọi lên vói tham số "sign" đợc gán giá trị -1, ví dụ, WTS(wr,wi,N,-1) và cho IFFT, WTS(wr,wi,N,1). Với IFFT, bạn cần chia dãy ra cho N trong chơng trình gọi hoặc là chơng trình chính. Bài tập 6.2 Kiểm tra chơng trình FFT bằng cách làm lại chơng trình 6.1. Chú ý rằng trong trờng hợp này bạn phải thêm các giá trị 0 để làm cho các dãy có chiều dài 2 4 = 16 và tất nhiên là lớn hơn chiều dài dãy nhỏ nhất đòi hỏi là (6 + 5 - 1). Mối tơng quan của hai dãy cho kết quả trong một tín hiệu tuần hoàn có chu kỳ bằng 16. 6.3.2 Thuật toán phân chia tần số. Thay vì chia dãy vào thành các vị trí chẵn và lẻ, chúng ta sẽ đa ra một chơng trình giống nh chơng trình trên nhng lần này ta bắt đầu từ dãy ra. Chơng trình này bao gồm các bớc sau: kn N N k nN N Nk kn N N k kn N W N kfWkf WkfWkfnF 12/ 0 2/ 1 2/ 12/ 0 ) 2 ()( )()()( Bây giờ, chia dãy F(n) thành hai dãy dựa trên giá trị chẵn và lẻ của n. )] 2 ()([)2( 2/ 2/).2( 12/ 0 kn N Nn N k W N kfWkfnF )] 2 ()([)12( )12( 2/ 2/).12( 12/ 0 nk N Nn N k W N kfWkfnF Chú ý rằng 0.1 2 njnN N eW 0.1 )12( 2/).12( nj Nn N eW Vì vậy 99 )] 2 ()([)2( 2/ 12/ 0 kn N N k W N kfkfnF ]) 2 ()([)12( 2/ 12/ 0 kn N k N N k WW N kfkfnF Đặt f k f k f k N 10 2 ( ) ( ) ( ) f k f k f k N W N k 11 2 ( ) [ ( ) ( )] Vì vậy .)()2( 2/ 12/ 0 10 kn N N k WkfnF (6.39) .)()12( 2/ 12/ 0 11 kn N N k WkfnF (6.40) Các biểu thức (6.39) và (6.40) có thể biểu diễn bằng dới dạng biểu đồ bớm nh trong hình 6.6. Chúng ta có thể tiếp tục chia nhỏ các tổng cho trong các biểu thức (6.39) và (6.40), tiếp tục làm nh vậy cho tới khi mỗi tổng giảm xuống chỉ còn lại một phần tử. Giải thuật này giống nh giải thuật thuật toán phân chia thời gian và để lại cho bạn nh một bài tập cho bạn. Một lu đồ cho FFT phân chia tần số với N = 4 trình bày trong hình 6.7. Bạn cần chú ý đến bậc của dữ liệu đầu ra là bit đợc đảo. Phần mềm thực hiện thuật toán trên thì rất giống phần mềm thực hiện FFT phân chia miền thời gian, và một chơng trình C đợc cung cấp ở Chơng trình 6.2. Có lẽ bạn sẽ tự hỏi: nếu phân chia miền thời gian đã thực hiện đợc công việc thì tại sao lại phải xem xét thêm FFT phân chia tần số. Để trả lời câu hỏi này, chúng ta sẽ cần xem xét phần kế tiếp, FFT giảm lợc. Chơng trình 6.2 FFTDF FFT phân chia tần số. 100 /**************************** * Program developed by: * * M.A.Sid-Ahmed. * * ver. 1.0 1992.1994 * *****************************/ /* FFT - Decimation-in-frequency routine.*/ #define pi 3.141592654 void bit_reversal (unsigned int *, int, int); void WTS(float *, float *, int, int) ; void FFT(float *xr, float *xi , float, float, int, int); void FFT (float *xr, float *xi, float *wr, float *wi, int m, int N) { /* FFT algorithm. Decimation-in-frequency algorithm. Note : 1. N=2 to the power of m. 2. The output arrays are left in bit-reverse order. You will need to use routine "bit-reversal" to place them in normal ascending order. 3. The twiddle factors are assumed to be stored in LUT's wr[j and wiEj. You will need to use routine LUT for calculating and storing twiddle factors. */ int ip,k,kk,l,incr,iter,j,i; float Tr,Ti,diffr,diffi; 101 H×nh 6.7 N = 4, ph©n chia miÒn tÇn sè FFT. ip= (N>>1) ; kk=1; incr=N; for(iter=0; iter<m; iter++) { for(j=0; j<N; j+=incr) { i=i+ip; Tr=xr[i]; Ti=xi[i]; xr[i]=xr[j]-Tr; xi[i]=xi[j]-Ti; 0 1 2 3 4 5 6 7 0 2 4 6 0 2 4 6 0 4 0 4 0 4 0 4 0 0 0 0 0 0 0 0 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 4 8 12 2 6 12 14 1 5 9 13 3 7 11 15 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 n W 8n W 4n W 2n W  102 xr[j]=xr[j]+Tr; xi[j]=xi[j]+Ti; } for(k=1;k<ip; k++) { l=k*kk-1; for(j=k; j<N; j+=incr) { i=j+ip; Tr=xr[j]+xr[i]; Ti=xi[j]+xi[i]; diffr=xr[j]-xr[i]; diffi=xi[j]-xi[i]; xr[j]=Tr; xi[j]=Ti ; Tr=diffr*wr[1]-diffi*wi[1]; Ti=diffr*wi[1]+diffi*wr[1]; xr[i]=Tr; xi[i]=Ti ; } } kk<<=1; ip>>=1 ; incr>>=1; } } 6.3.3 FFT giảm lợc Vấn đề có thể bắt đầu từ: cho 2 M điểm dữ liệu, chúng ta sẽ phải làm thế nào tính toán nhanh nhất khi dùng FFT có 2 L điểm ra với M L? Nếu M < L, có một số bớm sẽ bị giảm lợc (xem hình 6.8). Một giải thuật dựa trên tính toán các phần tử của bớm khi việc tính toán tất cả các phép tính là không cần thiết trong trờng hợp M < L gọi là giải thuật giảm lợc đầu vào FFT. Trong trờng hợp M > L thuật toán gọi là thuật toán giảm lợc đầu ra FFT. 103 Thuật toán giảm lợc đầu vào FFT. Trờng hợp này sẽ làm hoàn thiện hơn thuật toán phân chia tần số. Hình 6.8 giới thiệu trờng hợp M = 1 và L = 4. Từ hình 6.8 chúng ta nhận thấy (L-M) bớc đầu tiên có các phần tử bớm và L bớc cuối cùng có toàn bộ các bớm. Sơ đồ này giúp chúng ta thay đổi chơng trình 6.2 thành chơng trình 6.3. Chơng trình 6.3 "FFTIP.C". Giảm lợc đầu vào FFT. /**************************** * Program developed by: * * M.A.Sid-Ahmed. * * ver. 1.0 1992. * * @ 1994 * ***************************/ /* FFT - input pruning routine. */ void bit_reversal(unsigned int *, int , int); void WTS(float *, float *, int, int); void FFTP(float *xr, float *xi, float *, float *, int,int,int, int); void FFTP(float *xr, float *xi, float *wr, float *wi, int m_output, int N_output, int m_input, int N_input ) { /* FFT pruning algorithm. Deimation-in-frequency algorithm. Note: 1. Noutput=2 to the power of m_output. N_output=Number of samples in the output sequence. M_input=Number of samples in the input sequence. This should also be a multiple of 2. 2. The output arrays are left in bit-reverse order. You will need to use routine "bit-reversal" to place them in normal ascending order. 104 3. The twiddle factors are assumed to be stored in LUT's wr[I and wi[I. You will need to use routine LUT for calculating and storing twiddle factors. */ int ip,k,kk,l,inc r,iter,j,i; float Tr,Ti,diffr,diffi; ip=N_output>>1; kk=l ; incr=N_output; for(iter=0; iter<(m_output-m_input); iter++) { for(j=0; j<N_output; j+=incr) { i=i+ip ; xr[i]=xr[j]; xi[i]=xi[j]; } for(k=l; k<N_input; k++) { l =k*kk- 1 ; for(j=k; j<N_output; j+=incr) { i=j+ip ; xr[i]=xr[j]*wr[l]-xi[j]*wi[l]; xi[i]=xr[j]*wi[l]+xi[j]*wr[l]; } } kk<<=1; ip>>=1; incr>>=1; } 0 1 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15 0 4 8 12 2 6 10 14 1 5 9 13 3 7 11 15 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 W - n W - 6n W - 4n W - 2n . xi[i]=xi[j]-Ti; 0 1 2 3 4 5 6 7 0 2 4 6 0 2 4 6 0 4 0 4 0 4 0 4 0 0 0 0 0 0 0 0 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 4 8 12 2 6 12 14 1 5 9 13 3 7 11 15 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 n W 8n W 4n W 2n W  . 10 12 14 1 3 5 7 9 11 13 15 0 4 8 12 2 6 10 14 1 5 9 13 3 7 11 15 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 . 0 1 2 3 4 5 6 7 0 2 4 6 0 2 4 6 0 4 0 4 0 4 0 4 0 0 0 0 0 0 0 0 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15 0 4 8 12 2 6 12 14 1 5 9 13 3 7 11 15 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 n W 8n W 4n W 2n W  102 xr[j]=xr[j]+Tr; xi[j]=xi[j]+Ti;

Ngày đăng: 29/07/2014, 04:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan