搬运自己一篇FFTW的文章

最近(其实是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。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值