FFT----C语言(新手创作)

快速傅里叶FFT----C语言版本

presented by YanKM

由于个人纯属新手写md文件,故:尽量看吧(哈哈哈哈)

FFT这个东西据说比DFT要快许多,应为时间的复杂度变了,从原来的O(n^2)降到了O(nlogn)。对于整个FFT的介绍大家可以看看详细的算法介绍和推导过程维基百科

在这里,我们重点对整个代码框架做一个介绍

1. 复数

记住,这里我们说C语言并不是MATLAB,所以复数的运算我们得要自己定义

    typedef struct comp {
   
        double real;
        double imag;
    }Complex;

还有相应的运算(加、减、乘)

    Complex add (Complex a, Complex b){
   
        Complex c;
        c.real = a.real + b.real;
        c.imag = a.imag + b.imag;
        return c;
    }

    Complex sub (Complex a, Complex b){
   
        Complex c;
        c.real = a.real - b.real;
        c.imag = a.imag - b.imag;
        return c;
    }

    Complex mul (Complex a, Complex b){
   
        Complex c;
        c.real = a.real * b.real - a.imag * b.imag;
        c.imag = a.real * b.imag + a.imag * b.real;
        return c;
    }

这些不是这里的重点内容,不会的话可以复习一下复数的基本运算

2. 计算等级分割及重新排序

既然运算等级是O(nlogn),那么必然有个log(n)的级别,这就来源于等级分割。
我们先看几个例子:

个数 等级层数
4 2
8 3
2^n n

所以我们可以对于个数可以直接进行log2(N)即可。但是log运算得要用第三方库(math.h),且运算耗时,我们直接可以进行手动计算次数(毕竟N都是2的幂指数)

    tmp = N;
    while (tmp != 0) {
   
        tmp /= 2;
        times++;
    }
    times--;

然后我们来看一下重新排序。这个就有点操作了,举例为先:

原顺序 新顺序
0123 0213
01234567 04261537

可能我们对这些数字并不敏感(我也是一样),个人先想到这个有点像最大堆的拆分过程,然而实际上可以说这是对的(真香)。

上面哪个方法,可以用,自己也尝试了一下,空间占用很是问题。假如我们在开发板上用那种递归搞,俩字:呵呵

还有一种空间占用小且速度快的一种思路,从二进制的角度看问题,由于是八个数,所以索引编号从000到111即可,故前面的第二组数字为例,看一下变化:

0 1 2 3 4 5 6 7
000 001 010 011 100 101 110 111
0 4 2 6 1 5 3 7
000 100 010 110 001 101 011 111

可以发现二进制的顺序直接颠倒(001->100,110->011),所以对于颠倒我们看可以使用堆栈

所以有下面的代码

    int buf = (int*) malloc (times * sizeof(int));
    for (i = 0; i < length; i++) {
   
        tmp = i;
        // push
        for (j = 0; j < times; j++) {
   
            buf[j] = tmp % 2;
            tmp /= 2;
        }
        tmp = 0;
        // pop
        for (j = 0; j < times; j++) {
   
            tmp *= 2;
            tmp += buf[j];
        }
        number[i] = tmp;
    }

所以对于重新排序的整体代码就出锅了。

    int* change (int length) {
   
        int* number = (int*) malloc (length * sizeof(int));
        int* buf;
        int i = 0, times = 0, j = 0, k = 0; int tmp = length;
        while
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值