QT中使用FFTW库做FFT,编译器为mingw32

QT中使用FFTW库做FFT,编译器为mingw32

FFT在工程中很重要,总觉得自己写的FFT速度慢,所以我就去找了目前效果比较好的FFT库—FFTW使用。

  • QT中使用FFTW库做FFT编译器为mingw32
    • 什么是FFT
    • 第一步下载FFTW
    • 第二步创建lib文件
    • 第三步qtcretor设置

什么是FFT

快速傅里叶变换(英语:Fast Fourier Transform, FFT),是计算序列的离散傅里叶变换(DFT)或其逆变换的一种算法。傅里叶分析将信号从原始域(通常是时间或空间)转换到频域的表示或者逆过来转换。FFT会通过把DFT矩阵分解为稀疏(大多为零)因子之积来快速计算此类变换。1 因此,它能够将计算DFT的复杂度从只用DFT定义计算需要的 O(n2) ,降低到 O(nlogn) ,其中 n 为数据大小。
快速傅立叶变换广泛的应用于工程、科学和数学领域。这里的基本思想在1965年才得到普及,但早在1805年就已推导出来。1994年吉尔伯特·斯特朗把FFT描述为“我们一生中最重要的数值算法”,它还被IEEE科学与工程计算期刊列入20世纪十大算法。4—— [ 维基百科 ]

一般来说FFT的取点都是以2为底的指数,例如64点,512点,1024点等。但是实际上有时候又会去不到正好是1024点,例如只有1000点,这样会使转换后的结果有一些不一样。为了解决这个问题,我去stackoverflow查了一下,发现MATLAB已经做了一些修正。由于这次是工程应用,所以我使用matlab2016b(MOOC版)做参考,和FFTW的结果做对比,发现结果基本一致。所以最后才选择了FFTW这个库。
由于FFTW的商业版本需要收费,之前看stackoverflow上说大概8000美元,所以~

由于项目原因,我又不得不把它改写成c++代码。对于c++来说,FFT又是个麻烦事。顺便记录一下如何使用FFTW这个库。

编译环境如下:

  • OS:Windows 7
  • IDE:QT Creator 4+
  • QT版本:5.7
  • 编译器:mingw32

事实上我只是在win7下用官方的安装包安装了qt+qtcreator而已啦。

第一步:下载FFTW

FFTW是自由软件,它是GPL协议的库2。所以根据GPL协议,不要在商业软件里用这个库,除非给钱用商业版本。
这里我下载了dll,就是图省事。windows下编译fftw容易出问题,fftw团队自己都是用跨平台的编译器编译的。

第二步:创建lib文件

使用visual studio里面的lib工具,跑到fftw的dll目录下,运行:

lib /def:libfftw3-3.def
lib /def:libfftw3f-3.def
lib /def:libfftw3l-3.def

对于64-bit,

lib /machine:x64 /def:libfftw3l-3.def

我使用的是vs2015 community,经测试没问题。
生成

libfftw3-3.lib

libfftw3-3f.lib

libfftw3-3l.lib

.a和.lib后缀的库在qt中都可以用,如果需要.a的库直接重命名libfftw3-3.lib,我这里测试了libfftw3-3.lib,没有问题。

第三步,qtcretor设置

打开pro配置文件
加入以下几行:

QT += core
QT -= gui

CONFIG += c++11

TARGET = fftw_test
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

SOURCES += main.cpp

HEADERS += \
    fftw3.h
FFTWPATH = "C:\svn\fftw-3.3.5-dll32"



win32: LIBS += C:/svn/fftw-3.3.5-dll32/libfftw3-3.dll

INCLUDEPATH += $$PWD/C:/svn/fftw-3.3.5-dll32
DEPENDPATH += $$PWD/C:/svn/fftw-3.3.5-dll32

添加 LIBS += C:/svn/fftw-3.3.5-dll32/libfftw3-3.dll

这个还有一堆具体的讨论,说如何往qt pro文件中添加lib,详情可以见链接4

最后,
添加头文件 #include “fftw3.h”
下面是个简单的例子:

#include 
#include "fftw3.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    int N = 151;
    fftw_complex *in, *out;
    fftw_plan p;
    //add code;
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
    p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
    //add code;
    for (int i = 0; i < N; i++)
    {
        in[i][0] = sin(i);//real
        in[i][1] = 0;//image
    }
    fftw_execute(p); /* repeat as needed */
    //add code;
    for (int i = 0; i < N; i++)
    {
        qDebug()<0]<<","<1];
    }
    fftw_destroy_plan(p);
    fftw_free(in); fftw_free(out);
    qDebug()<<"bye";
    return 0;
}

你可能感兴趣的:(QT)