傅里叶变换的C语言版本FFTW目前已全面支持fftw3,目前最新版本为fftw3.3.8,可以在其官网上查看:FFTW。
然而有一些科学算法的C语言源代码是基于fftw的旧版本fftw2.1.5开发的,在调用时需要有编译好的fftw2.1.5的dll支持。
因笔者水平有限,为了编译fftw2.1.5,查阅各种资料,花费了很多时间,尝试了各种方法,终于成功了。笔者通过实践发现成功编译的方法不止一种。
本文结合笔者的实际操作,介绍了其中一种简单的方法:如何在Windows编译fftw2.1.5,从而得到可以灵活调用的动态链接库。
准备:在FFTW的官网上下载fftw2.1.5版的源码。
一、MSYS2的安装
1.1 下载安装
按照官网教程安装即可。
MSYS2官网:MSYS2
Minimal GNU(POSIX)system on Windows,是一个小型的GNU环境,包括基本的bash,make等等。与Cygwin大致相当。如果你想学习linux环境下的编程,而又不想装linux,那你就装一个MinGW吧。(语出百度百科)
1.2 更新MSYS2
pacman -Syu
更新过程中要求重启,直接关掉窗口(不可ctrl+a等结束),之后重新打开窗口输入
pacman -Su
二、 安装编译环境
2.1 安装gcc
执行下面的命令安装与MinGW-w64匹配的gcc
命令: pacman -S mingw-w64-x86_64-gcc
2.2 安装make
命令: pacman -S make
2.3 添加环境变量
将MingGW-w64以及msys2的bin目录添加到系统路径;如下:
三、编译FFTW_2.1.5
核心方法是将C语言源码的.c文件编译为dll文件。
3.1 .c文件编译为dll文件
打开msys minw64 bit
进入到fftw_2.1.5文件夹下的fftw文件夹
输入命令:gcc *.c -shared -o fftw2.dll -Wl,--output-def,fftw2.def
回车即可在同文件夹下生成fftw2.dll和fftw2.def文件。
3.2 dll文件生成lib文件
用vs(Visual Studio)自带的命令提示编译,笔者用的是vs2008。
进入dll文件所在文件夹
输入命令:lib /machine:X64 /def:fftw2.def
回车即可生成.lib文件
经过上述操作,得到我们想要的以下文件:
这样就可以通过动态链接库来调用fftw2.1.5了。
还有一种方法是:先将源码.c文件编译为.o文件,再将.o文件编译为.dll文件。
四、使用FFTW_2.1.5
为了检验编译结果的正确性,下面用一个简单地傅里叶变换的例子来说明。
新建项目
包含目录、库目录输入fftw2所在文件夹路径
附加依赖项填写fftw2.lib
注意,fftw2.dll文件要与程序代码同目录
测试代码如下:
#include <stdlib.h>
#include <time.h>
#include "fftw.h"
int main()
{
fftw_complex *in, *out;
int N = 10;
in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
printf("Original array:\n");
for (int i = 0; i < N; i++)
{
c_re(in[i]) = 1.0;
c_im(in[i]) = 0.0;
printf("%6.2f ", in[i].re);
}
printf("\n");
// 傅里叶正变换
clock_t start = clock();
fftw_plan p;
p = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_one(p, in, out);
printf("\nFourier transform array:\n");
for (int j = 0; j < N; j++)
{
printf("%6.2f ", out[j].re);
}
clock_t end = clock();
printf("\n");
printf(" FFTW : %f second\n", (double)(end - start) / CLOCKS_PER_SEC);
// 傅里叶反变换
fftw_plan q = fftw_create_plan(N, FFTW_BACKWARD, FFTW_ESTIMATE);
fftw_complex *out2 = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N);
fftw_one(q, out, out2);
printf("\nInverse fourier transform array:\n");
for (int j = 0; j < N; j++)
{
printf("%6.2f ", out2[j].re/N); // 反变换需要除以数组长度
}
printf("\n");
fftw_destroy_plan(p);
fftw_destroy_plan(q);
fftw_free(in);
fftw_free(out);
fftw_free(out2);
system("PAUSE");
return 0;
}
运行结果:
我们用MATLAB自带的傅里叶变做对比:
结果一致。完美成功!撒花~
参考博文
1.Windows 编译 FFTW 2/3 以及安装CurveLab
2.msys2在windows10系统的安装
3.FFTW 3.1.2 和 2.1.5编译
4.C++学习 | VS2015下配置FFTW3库的方法,亲测实用
5.MSVC 和 minGW .a .dll 等文件之间转换
6.FFTW2.1.5用法介绍