2012-01-10 39 views
19

Tôi đang tìm kiếm một FFT thực hiện trong C. Tuy nhiên, tôi không tìm kiếm một thư viện lớn (như FFTW) nhưng cho một dễ sử dụng duy nhất C-file thực hiện. Thật không may tôi đã không thể tìm thấy bất cứ điều gì như thế này.FFT trong một C-file duy nhất

Ai đó có thể đề xuất triển khai đơn giản?

+0

Hãy thử [tìm kiếm 'fft' trên github] (https://github.com/search?langOverride=c&q=fft&repo=&start_value=1&type=Repositories). Nhưng những gì không dễ sử dụng về FFTW? Bạn có nghĩa là dễ hiểu nguồn? – Rup

+9

Viết của riêng bạn. Nó sẽ là một bài tập tốt. Internet có đầy đủ các giải thích về cách tính DFT và FFT. Dùng nó. –

+1

Các thói quen FFT [ở đây] (http://www.fit.vutbr.cz/research/prod/?id=510) có ít hơn một trăm dòng mã. Thư viện thực hiện các thuật toán biến đổi Fourier nhanh (FFT) chuyển tiếp và đảo ngược nhanh chóng bằng cách sử dụng cả decimation in time (DIT) và decimation in frequency (DIF). – DaBler

Trả lời

20

Đặt cược tốt nhất của bạn là KissFFT - như tên gọi của nó ngụ ý là simple, nhưng nó vẫn khá nhanh chóng đáng kính và nhẹ hơn nhiều so với FFTW. Nó cũng miễn phí, FFTW yêu cầu một khoản phí giấy phép khổng lồ nếu bạn muốn đưa nó vào một sản phẩm thương mại.

+1

Chỉ khi bạn đang phân phối lại nó, và không giải phóng nguồn theo GPL ... –

+1

Đó chính xác là những gì tôi đang tìm kiếm. Cảm ơn nhiều. – mijc

7

Tệp này hoạt động bình thường như trước: chỉ cần sao chép và dán vào máy tính của bạn. Lướt web trên web Tôi đã tìm thấy triển khai dễ dàng này trên trang wikipedia here. Trang này bằng tiếng Ý, vì vậy tôi đã viết lại mã bằng một số bản dịch. Here có hầu hết các thông tin tương tự nhưng bằng tiếng Anh. THƯỞNG THỨC!

#include <iostream> 
#include <complex> 
#define MAX 200 

using namespace std; 

#define M_PI 3.1415926535897932384 

int log2(int N) /*function to calculate the log2(.) of int numbers*/ 
{ 
    int k = N, i = 0; 
    while(k) { 
    k >>= 1; 
    i++; 
    } 
    return i - 1; 
} 

int check(int n) //checking if the number of element is a power of 2 
{ 
    return n > 0 && (n & (n - 1)) == 0; 
} 

int reverse(int N, int n) //calculating revers number 
{ 
    int j, p = 0; 
    for(j = 1; j <= log2(N); j++) { 
    if(n & (1 << (log2(N) - j))) 
     p |= 1 << (j - 1); 
    } 
    return p; 
} 

void ordina(complex<double>* f1, int N) //using the reverse order in the array 
{ 
    complex<double> f2[MAX]; 
    for(int i = 0; i < N; i++) 
    f2[i] = f1[reverse(N, i)]; 
    for(int j = 0; j < N; j++) 
    f1[j] = f2[j]; 
} 

void transform(complex<double>* f, int N) // 
{ 
    ordina(f, N); //first: reverse order 
    complex<double> *W; 
    W = (complex<double> *)malloc(N/2 * sizeof(complex<double>)); 
    W[1] = polar(1., -2. * M_PI/N); 
    W[0] = 1; 
    for(int i = 2; i < N/2; i++) 
    W[i] = pow(W[1], i); 
    int n = 1; 
    int a = N/2; 
    for(int j = 0; j < log2(N); j++) { 
    for(int i = 0; i < N; i++) { 
     if(!(i & n)) { 
     complex<double> temp = f[i]; 
     complex<double> Temp = W[(i * a) % (n * a)] * f[i + n]; 
     f[i] = temp + Temp; 
     f[i + n] = temp - Temp; 
     } 
    } 
    n *= 2; 
    a = a/2; 
    } 
} 

void FFT(complex<double>* f, int N, double d) 
{ 
    transform(f, N); 
    for(int i = 0; i < N; i++) 
    f[i] *= d; //multiplying by step 
} 

int main() 
{ 
    int n; 
    do { 
    cout << "specify array dimension (MUST be power of 2)" << endl; 
    cin >> n; 
    } while(!check(n)); 
    double d; 
    cout << "specify sampling step" << endl; //just write 1 in order to have the same results of matlab fft(.) 
    cin >> d; 
    complex<double> vec[MAX]; 
    cout << "specify the array" << endl; 
    for(int i = 0; i < n; i++) { 
    cout << "specify element number: " << i << endl; 
    cin >> vec[i]; 
    } 
    FFT(vec, n, d); 
    cout << "...printing the FFT of the array specified" << endl; 
    for(int j = 0; j < n; j++) 
    cout << vec[j] << endl; 
    return 0; 
} 
+2

Đó là thực sự ngắn gọn đáng ngạc nhiên. – Vortico

+0

dễ hiểu và quan trọng hơn, nó hoạt động tốt. Ngoài ra bạn có thể dễ dàng sửa đổi nó để thích ứng với nhiệm vụ của bạn – Leos313

+0

làm thế nào để làm FFT nghịch đảo với mã này? – alexandrecosta

Các vấn đề liên quan