FFT的C语言库FFTW的Windows和linux安装使用方法

机子里的FFTW库下了很长时间了,总也没有去搞。唉,有很多东西就是这样,千方百计搞过来,搞到手了就晾在那里了。记得《黄生借书说》里面说得对啊“书非借不能读也”。

好了,感慨完毕。归入正题。

Windows下FFTW库的安装

1、  从网址http://www.fftw.org/install/windows.html上获得FFTW的windows dll预编译版本;

2、  解压缩文件,打开windows命令行窗口,就是那个cmd窗口啦。然后把当前目录转换到你解压缩文件的目录下。

3、  执行以下3个指令(在ix86和/def:libfftw3-3.def之间没有加空格会造成错误)

lib /machine:ix86 /def:libfftw3-3,def
lib /machine:ix86 /def:libfftw3f-3.def
lib /machine:ix86 /def:libfftw3l-3.def

这会在该目录下建三个相应的dll文件和lib文件。注意第三个.def文件中的“3l-3”中的是字母L的小写,不是数字一。因为这个问题,我搞了半个小时,呵呵。

4、  将libfftw3l-3.dll, libfftw3f-3.dll, libfftw3-3.dll 文件复制到文件夹system32中。这一步是为了你以后都不用在你的可执行文件所在的文件夹中带上这3个拖油瓶,因为系统直接会去system32中找。

5、  在 VC 中指定 libfftw3l-3.lib, libfftw3f-3.lib, libfftw3-3.li這3個lib文件及 fftw3.h 文件所在的目录。也就是在vc++的tools->options的 Directories选项中的Include Files和Library Files中把这两个目录加上,使得以后VC编译的时候知道该到哪个目录中去找。

6、  最后一步就是,在你新建工程的时候,记得#include“fftw3.h”,然后把你要用的lib写到Project->setting->link->General里面的Object/library modules里面去。

7、  下面,你就可以放心大胆地去使用fftw的库编程了。为了熟悉FFTW的调用方式和数据结构,你还可以从http://www.fftw.org/#documentation下载一份manual好好钻研钻研。

 

可能出现的错误:

1.      LNK1181:cannot open input file“…”: 出现这个错误的原因有: (1)你文件名打错了; (2) 你的当前目录不对,当前目录应该是你解压后的文件目录。

2.      源文件编译时报找不到lib,那是因为你第5步或第6步没做好,建议重做一下第5步和第6步。

 

使用FFTW编写测试程序

  上面的搞好后,就写一个小的测试代码试一下效果。我就抄了一个网上的代码:

#include "fftw3.h"
int main()
{
    fftw_complex *in, *out;
    fftw_plan p;
    int N= 8;
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    for( int i=0; i < N; i++)
           {
        in[i][0] = 1.0;
        in[i][1] = 0.0;
        printf("%6.2f ",in[i][0]);
        }
    printf("\n");  // in 是输入的数据
    p=fftw_plan_dft_1d(N,in,out, FFTW_FORWARD, FFTW_ESTIMATE);
    fftw_execute(p); /* repeat as needed*/
    for(int j = 0;j < N;j++)
          {
        printf("%6.2f ",out[j][0]);
          }
    printf("\n");
    fftw_destroy_plan(p);
    fftw_free(in);
    fftw_free(out);
    return 0;
}

 

程序给了一个直流的时域数据,应该出来一个只有直流分量的DFT数据。

 

Linux下FFTW库的安装

FFTW(the Fastest Fourier Transform in the West)库是由MIT(Massachusetts Institute of Technology)的Matteo Frigo和Steven G. Johnson开发的,用于一维和多维实数或复数的离散傅里叶变换。

1. 下载 fftw-2_1_3_tar.gz              (www.fftw.org, or www.rpmfind.net


2. tar zxvf fftw-2_1_3_tar.gz            展开压缩文件


3. 在Linux中安装FFTW:

a.    

./configure --enable-type-prefix --prefix=/usr/local/fftw --with-gcc --disable-fortran --enable-i386-hacks

     

其中,

--enable-type-prefix    参数是为了同时使用single precision(单精度)和double precision(双精度),如果不使用它,最后只有以rfftw开头的文件被安装(real fftw);

--prefix=                      参数是设定安装目录;

--with-gcc                    使用gcc编译器;

--disable-fortran         参数为了不包含Fortran调用的机制;

--enable-i386-hacks   为Pentium和x86以后的CPU优化gcc的编译速度。


b.

make                          编译


c.

make install               安装,这一次安装完后,在安装目录中存在以dfftw和drfftw开头文件,但没有sfftw开头的文件


d.

make clean              还需要安装一次,先清除


e.

./configure --enable-float --enable-type-prefix --prefix=/usr/local/fftw --with-gcc --disable-fortran --enable-i386-hacks


其中,--enable-float      为了生成单精度计算的头文件和库文件,即以sfftw开头的文件。


f.

make                      重新编译


g.

make install            再一次安装,安装完后,目录中便会同时存在sfftw和dfftw开头的文件(用于复数函数/complex function的FFT变换)和srfftw与drfftw开头的文件(用于实数函数的FFT变换)


例如,如果需要用到双精度的实数FFT变换/FFTs,那么在编译的链接命令中需要按如下顺序加入
-ldrfftw -ldfftw参数


下面的是如何使用的一个例子
/*****************************
* filename: test_fftw.cpp
* author : Tiao Lu
* Company : School of Mathematical Sciences, Peking University
* 编译命令: g++ -o test_fftw.exe test_fftw.cpp -lfftw3
* Date    : September 30th, 2007
* Description: This code is an example to show the use of the free code FFTW, which implements the Fast Fourier Trasformation algorithm.
*/

#include <complex>
#include <fftw3.h>
#include <math.h>
#include <iostream>

#define N 10
using namespace std;
int main(int argc, char * argv[]){

    fftw_complex in[N], out[N];
    fftw_plan p;

//一维dft,in 输入,out输出,FFTW_FORWARD 表示 exp 上指数是负号
// out = F in
//where out and in are two vectors of the same length n, and F is a n-by-n matrix with the (j,k) element
// F jk = exp(-i 2 pi j k /n). i 是虚数单位.

    p=fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_MEASURE);
    for(int i=0;i <N;i ++) {
        in[i][0]=i;
        in[i][1]=0.0;
    }
  

    fftw_execute(p);

    for(int i=0;i <N;i ++){
        cout<<out[i][0]<<" "<<out[i][1]<<endl;
    }

    //验证是否 out[3] = \sum_{k=0}^{N-1}exp(-i 2pi 3 k/N)in[k]
    complex<double> temp = 0.0;
    for(int k =0; k < N; k ++){
        double pi = 4*atan(1.0);
        temp += exp(complex<double>(0.0,-2.0*pi*3*k/N))*complex<double>(in[k][0],in[k][1]);
    }
    cout<<"out[3] is "<<temp<<endl;

    fftw_complex out1[N];

    fftw_plan p1;
//一维dft,in 输入,out输出,FFTW_BACKWARD 表示 exp 上指数是正号
// out = IF in
//where out and in are two vectors of the same length n, and IF is a n-by-n matrix with the (j,k) element
// IF jk = exp( +i 2 pi jk/n). i 是虚数单位.

    p1=fftw_plan_dft_1d(N,out1,in,FFTW_BACKWARD,FFTW_MEASURE);

    for(int i=0;i <N;i ++){
        out1[i][0]=out[i][0];
        out1[i][1]=out[i][1];
    }

    fftw_execute(p1);
//注意这里得到的 in 并不是和原来的in 的数值不同,比较之后发现,现在的in
// 是原来的 in 的 N 倍。原因是这里的定义的逆傅立叶变换没有除以 N.
//这和课本中定义的逆傅立叶变换不同。
    for(int i=0;i <N;i ++){
        cout<<in[i][0]<<" "<<in[i][1]<<endl;
    }



    fftw_destroy_plan(p);
    fftw_destroy_plan(p1);
    return 1;
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用C语言标准实现FFT(快速傅里叶变换)可以通过以下步骤进行: 1. 引入头文件:首先需要引入C语言标准中的math.h头文件,该头文件中包含了进行数学计算的函数。 2. 定义复数结构体:由于FFT涉及到复数运算,需要定义一个复数结构体来表示复数。可以使用以下代码定义一个复数结构体: ```c typedef struct { double real; double imag; } Complex; ``` 3. 实现FFT算法:根据FFT算法的原理,可以编写一个函数来实现FFT。以下是一个简单的FFT实现示例: ```c #include <stdio.h> #include <math.h> #define PI 3.141592653589793238462643383279502884 typedef struct { double real; double imag; } Complex; void fft(Complex* x, int N) { if (N <= 1) { return; } Complex even[N/2]; Complex odd[N/2]; for (int i = 0; i < N/2; i++) { even[i] = x[2*i]; odd[i] = x[2*i + 1]; } fft(even, N/2); fft(odd, N/2); for (int k = 0; k < N/2; k++) { double angle = -2 * PI * k / N; Complex t = {cos(angle), sin(angle)}; t.real *= odd[k].real; t.imag *= odd[k].imag; x[k].real = even[k].real + t.real; x[k].imag = even[k].imag + t.imag; x[k + N/2].real = even[k].real - t.real; x[k + N/2].imag = even[k].imag - t.imag; } } int main() { int N = 8; // 输入序列的长度,必须是2的幂次方 Complex x[N]; // 初始化输入序列 for (int i = 0; i < N; i++) { x[i].real = i + 1; x[i].imag = 0; } // 执行FFT fft(x, N); // 输出结果 for (int i = 0; i < N; i++) { printf("X[%d] = %.2f + %.2fi\n", i, x[i].real, x[i].imag); } return 0; } ``` 在上述示例中,首先定义了一个复数结构体`Complex`,然后实现了一个递归的FFT函数`fft`。在`main`函数中,初始化了一个长度为8的输入序列,并调用`fft`函数进行FFT计算。最后输出了计算结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值