搬运自己一篇FFTW的文章

来源:互联网 发布:良品铺子手撕面包 知乎 编辑:程序博客网 时间:2024/06/06 06:49

最近(其实是15年9月左右)的项目中需要使用C语言实现二维傅立叶变换,无奈自己水平太低,创建不了一套傅立叶变换或者是快速傅立叶变换的函数库,只得求助于fftw。

初始的时候尝试着通过指针的指针来创建二维矩阵,的确,能够给创建,并且赋值,但是,无奈,fftw_plan_dft_2d函数的输入参数要求必须是指针型变量fftw_complex *,无法传递​​fftw_complex **,只好作罢,通过创建一维向量,但是逐段截取来作为二维矩阵,这样就可以解决传递地址的问题。

但是,这样做真的正确吗?我们不妨验证一下。验证的思路就是通过该方法来穿件二维矩阵,并且利用fftw做二维傅立叶变换,查看结果是否与matlab下面相同矩阵做fft2的结果一致。

C语言代码如下:

//通过这个程序好像可以发现fftw_free并不能真正的释放内存,只有free才可以释放内存//将第41行替换为fftw_free之后后面的打印仍旧能够正常,说明fftw_free并不能释放内存。#include<stdio.h>#include<fftw.h>#include<stdlib.h>int main(void){    int row,col;    int i,j;    fftw_complex * in;    fftw_complex * out;    fftw_plan p;    row = 8;    col= 8;    //申请一个行数乘以列数的一维向量,并且没列数个作为一行,以此来表示二维矩阵    in = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * row * col);    out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * row * col);    for(i=0;i<row;i++)    {        for(j=0;j<col;j++)        {            in[i*col+j][0] = 1;//通过col个数据表示一行,来逐行区分矩阵            in[i*col+j][1] = 1;        }    }    p = fftw_plan_dft_2d(row,col,in,out,FFTW_FORWARD,FFTW_ESTIMATE);    fftw_execute(p);    fftw_destroy_plan(p);    for(i=0;i<row;i++)    {        for(j=0;j<col;j++)        {            printf("%f\t%f\t\t",out[i*col+j][0],out[i*col+j][1]);        }        printf("\n");    }    printf("AHA!\n");    fftw_free(in);    free(out);//换为fftw_free之后后面的一段程序是能够正常工作的,说明并没有释放内存    for(i=0;i<row;i++)    {        for(j=0;j<col;j++)        {            printf("%f\t%f\t\t",out[i*col+j][0],out[i*col+j][1]);        }        printf("\n");    }    printf("AHA!\n");}

matlab的程序如下:

算了,五六行,自己写吧!

C语言运行结果如下:

仅有第一个数据的实部虚部均为64,其余元素均为0
在matlab运行后结果也是如此,所有的能量集中在零频(因为离散化的原因,显示在第一个数据上)。

附:​

在​验证这个的过程中,还出现了另外一个问题,就是C语言程序的41行如果我是用的是fftw带有的fftw_free来释放内存的话,会发现后面的printf仍旧能够直行,说明程序并没有释放内存,这个语句没有效果。但是换做普通的free之后,能够出现预期结果,后面部分结果打印不出来(这是正确的),所以,下一步可能是需要将程序中的所有的fftw_free全部替换为free。

0 0
原创粉丝点击