FFT变换的C语言实现

             FFT变换的C语言实现

1、安装FFTW3库文件

FFTW是用来计算一维或者多维的离散傅里叶变换,输入可以为实数序列也可以为复数序列的C语言的子函数库,FFTW是免费软件,是作为fft函数库的各种应用的上佳选择,这一开发库为美国麻省理工学院开发,是迄今为止世界上做好用的快速傅里叶变换的开发库,并且完全免费。

可以到下面链接:http://www.fftw.org/install/windows.html下载最新的已编译版本。


这里提供有32和64两个版本的下载链接,同时还有生成lib文件命令。即32位系统命令为: lib /def:libfftw3-3.def,而64位系统为:

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

下载适合自己版本解压后,会发现只有dll和头文件,在没有lib文件时,由于应用fftw编程时需要lib文件,所以这里需要使用上面的命令生成lib文件。首先打开VS命令提示工具。本人安装的为VS2015,选择打开vs2015开发人员命令提示(其他版本的也可以)。如下图所示:


打开命令行窗口后,使用cd命令切换到刚才下载文件的目录下,如图


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

将生成的我们需要的库文件libfftw3-3.liblibfftw3f-3.lib libfftw3l-3.lib。



2、FFTW库文件的使用

这里主要是指开发包中动态链接库libfftw3f-3.dll和静态链接库libfftw3f-3.lib

在第一步分别生成了double、float、long double三个版本,实际使用时可根据项目需要,选择相应精度的版本。

double版本:      libfftw3-3.dll     libfftw3-3.dll

float版本:        libfftw3f-3.dll     libfftw3f-3.dll

long double版本:  libfftw3l-3.dll     libfftw3l-3.dll

(一)、动态链接库(libfftw3-3.dll)的调用方法

      (1)、直接将动态链接库(libfftw3-3.dll)复制到项目的当前目录即可使用

      (2)、将动态链接库(libfftw3-3.dll)复制到系统文件夹下,windows/system32中。

问题一:本人是64window7,有三个文件夹,windows/systemwindows/system32windows/SysWOW64,当放在systemSysWOW64文件夹下面时,可以正常使用,但当放在system32文件夹(不放在其他文件夹)下面时,会出现缺失此动态链接库(libfftw3-3.dll)的错误。

为此本人搜索了网上的关于这3个系统文件夹的区别,但还是不能解决问题

32位和64位操作系统与SystemSystem32Syswow64的区别

https://www.ssdax.com/196.html

32位的Windows操作系统可以同时运行32位和16位代码,而64位Windows操作系统可以直接运行64位代码,同时通过使用WoW64(Windows on Windows 64)也能运行32位代码。

    32位版本的Windows在如何允许32为和16位代码并肩运行方面有着很复杂的机制,然而64位版本的Windows就不同了,32位代码与64位代码单独运行,有着两个Program Files,有着system32和syswow64两个DLL文件夹,甚至两个注册表。

    在32位操作系统的Windows文件夹中,SYSTEM和SYSTEM32两个文件夹,分别用来存放16位和32位的DLL文件。

如果按照这个规律,存放64位系统的DLL文件的文件夹应该叫:System64,但实际上存放64位DLL的文件夹依然叫:System32,同时又多了一个SysWow64文件夹。

   现在的软件大多是32位软件,所以默认会将DLL文件放到System32文件夹中,而微软为了保障兼容性,所以无论是32位还是64位的DLL文件都是放到了System32文件夹中。

那SysWoW64文件夹又是干什么用的呢?这是因为32位软件并不能在64位系统中直接运行,所以微软设计了WoW64(Windows-on-Windows 64-bit),通过Wow64.dll、Wow64win.dll、Wow64cpu.dl三个DLL文件进行32位和64位系统的切换来运行32位软件。

所以在64位系统中,DLL复制到System32文件夹中即可

(二)、静态链接库(libfftw3-3.lib)的调用方法

(1)、当直接讲.lib文件复制到项目的当前文件夹时,在程序的中只需要使用#pragma comment(lib,”******”);语句即可

(2)、当不使用#pragma comment(lib,”******”)时,这时候需要做两个事情,第一个是需要将.lib文件拷贝到vc++6.0的安装目录的lib文件下。我这里的是C:\Program Files (x86)\MicrosoftVisual Studio\VC98\Lib第二步需要配置一下vc++6.0的链接环境,以便能够顺利的链接需要的库文件,这里配置vc++6.0:projectàsettingsàlinkàCateGory中选择inputà将.lib文件名加入到Object/library modules中,如图所示


做完这些,既可以开始用FFTW3开始顺利开发了(这里有个提示:操作系统版本虽然是64位的,但是vc++6.0是32位的,所以使用FFTW3时要使用32位的,不然程序在链接时会出现机器类型不匹配的错误)

 

这里贴出调试过的源代码:参考出处:http://blog.csdn.net/grafx/article/details/38750107?utm_source=tuicool&utm_medium=referral

#include"stdafx.h"

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

   

#include"include/fftw3.h"

#pragma comment(lib,"libfftw3-3.lib");//加载静态链接库

 

#define PI 3.1415926

 

int main()

{

   int len=8;

   double *in= NULL;

   //如果要使用float版本,需先引用float版本的lib库,

   //然后在fftw后面加上f后缀即可

   fftw_complex*out = NULL;//fftwf_complex -->即为float版本

   fftw_planp;

   in =(double *)fftw_malloc(sizeof(double)*len);

   out =(fftw_complex *)fftw_malloc(sizeof(fftw_complex)*len);

   double dx= 1.0/len;

              

   //输入纯实数

   for(inti=0; i<len; i++)

   {

      in[i] =sin(2*PI*dx*i) + sin(4*PI*dx*i);

      printf("%.2f    ",in[i]);

   }

   printf("\n\n");

  

   //傅里叶变换

   p =fftw_plan_dft_r2c_1d(len,in,out,FFTW_ESTIMATE);

   fftw_execute(p);

 

   //输出幅度谱

   for(intj=0; j<len; j++)

   {

      floatlen = sqrt(out[j][0]*out[j][0] + out[j][1]*out[j][1]);

      printf("%.2f    ",len);

   }

   printf("\n");

 

   //释放资源

   fftw_destroy_plan(p);

   fftw_free(in);

   fftw_free(out);

 

   system("pause");

   return 0;

}


FFTW的使用指南:参考:http://wenku.baidu.com/link?url=vKDRs7cwF4pQq-IjMlxwAsg3YkV-GxH5Ih2wLK7B40HoK7mPboNNmT9yxJ1U1zn8ynbyC6URg6Mgw84w-OC0lWfrELPvW_QgtUR9SiuBglG

1、fftw基本结构












  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
快速傅里叶变换(Fast Fourier Transform,FFT)是一种高效的算法,用于快速计算离散傅里叶变换(Discrete Fourier Transform,DFT)。它可以将一个序列转换为其频率分量。 在C语言中,实现快速FFT变换可以使用递归或迭代的方式。以下是一个用C语言实现快速FFT变换的简单示例: 首先,需要定义一个复数结构体,用来存储实部和虚部: ```c typedef struct { double real; double imag; } Complex; ``` 接下来,实现关键的FFT函数: ```c void fft(Complex arr[], int size, int inverse) { if (size <= 1) { return; } Complex even[size / 2]; Complex odd[size / 2]; // 分离奇数项和偶数项 for (int i = 0; i < size / 2; i++) { even[i] = arr[2 * i]; odd[i] = arr[2 * i + 1]; } // 递归计算奇数项和偶数项的FFT fft(even, size / 2, inverse); fft(odd, size / 2, inverse); // 计算每个频率分量 double angle = 2 * PI / size * (inverse ? -1 : 1); Complex w = {1, 0}; Complex wn = {cos(angle), sin(angle)}; for (int i = 0; i < size / 2; i++) { Complex temp = mult(w, odd[i]); arr[i] = add(even[i], temp); arr[i + size / 2] = sub(even[i], temp); if (inverse) { arr[i] = div(arr[i], 2); arr[i + size / 2] = div(arr[i + size / 2], 2); } w = mult(w, wn); } } ``` 其中,mult、add、sub和div是对复数进行乘法、加法、减法和除法的函数。 最后,在主函数中调用FFT函数: ```c int main() { Complex arr[N]; // 输入序列 // 初始化输入序列 // ... fft(arr, N, 0); // 进行正向FFT变换 // 输出频率分量 for (int i = 0; i < N; i++) { printf("%f + %fi\n", arr[i].real, arr[i].imag); } return 0; } ``` 这样就可以实现快速FFT变换的功能了。快速FFT变换在信号处理、图像处理以及其他科学和工程领域中都有广泛的应用。它通过减少计算量,大大提高了傅里叶变换的计算效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值