打印
[学习资料]

C语言FFT

[复制链接]
1254|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dspmana|  楼主 | 2023-3-27 10:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/************FFT***********/

#include < stdio.h >
    #include < math.h >
    #include < stdlib.h >
    #define N 1000
typedef struct

{

    double real;

    double img;

}
complex;

void fft(); /*快速傅里叶变换*/

void ifft(); /*快速傅里叶逆变换*/

void initW();

void change();

void add(complex, complex, complex * ); /*复数加法*/

void mul(complex, complex, complex * ); /*复数乘法*/

void sub(complex, complex, complex * ); /*复数减法*/

void divi(complex, complex, complex * ); /*复数除法*/

void output(); /*输出结果*/

complex x[N], * W; /*输出序列的值*/

int size_x = 0; /*输入序列的长度,只限2的N次方*/

double PI;

int main()

{

    int i, method;

    system("cls");

    PI = atan(1) * 4;

    printf("Please input the size of x:\n");

    /*输入序列的长度*/

    scanf("%d", & size_x);

    printf("Please input the data in x[N]:(such as:5 6)\n");

    /*输入序列对应的值*/

    for (i = 0; i < size_x; i++)

        scanf("%lf %lf", & x[i].real, & x[i].img);

    initW();

    /*选择FFT或逆FFT运算*/

    printf("Use FFT(0) or IFFT(1)?\n");

    scanf("%d", & method);

    if (method == 0)

        fft();

    else

        ifft();

    output();

    return 0;

}

/*进行基-2 FFT运算*/

void fft()

{

    int i = 0, j = 0, k = 0, l = 0;

    complex up, down, product;

    change();

    for (i = 0; i < log(size_x) / log(2); i++)

    {

        l = 1 << i;

        for (j = 0; j < size_x; j += 2 * l)

        {

            for (k = 0; k < l; k++)

            {

                mul(x[j + k + l], W[size_x * k / 2 / l], & product);

                add(x[j + k], product, & up);

                sub(x[j + k], product, & down);

                x[j + k] = up;

                x[j + k + l] = down;

            }

        }

    }

}

void ifft()

{

    int i = 0, j = 0, k = 0, l = size_x;

    complex up, down;

    for (i = 0; i < (int)(log(size_x) / log(2)); i++) /*蝶形运算*/

    {

        l /= 2;

        for (j = 0; j < size_x; j += 2 * l)

        {

            for (k = 0; k < l; k++)

            {

                add(x[j + k], x[j + k + l], & up);

                up.real /= 2;
                up.img /= 2;

                sub(x[j + k], x[j + k + l], & down);

                down.real /= 2;
                down.img /= 2;

                divi(down, W[size_x * k / 2 / l], & down);

                x[j + k] = up;

                x[j + k + l] = down;

            }

        }

    }

    change();

}

void initW()

{

    int i;

    W = (complex * ) malloc(sizeof(complex) * size_x);

    for (i = 0; i < size_x; i++)

    {

        W[i].real = cos(2 * PI / size_x * i);

        W[i].img = -1 * sin(2 * PI / size_x * i);

    }

}

void change()

{

    complex temp;

    unsigned short i = 0, j = 0, k = 0;

    double t;

    for (i = 0; i < size_x; i++)

    {

        k = i;
        j = 0;

        t = (log(size_x) / log(2));

        while ((t--) > 0)

        {

            j = j << 1;

            j |= (k & 1);

            k = k >> 1;

        }

        if (j > i)

        {

            temp = x[i];

            x[i] = x[j];

            x[j] = temp;

        }

    }

}

void output() /*输出结果*/

{

    int i;

    printf("The result are as follows\n");

    for (i = 0; i < size_x; i++)

    {

        printf("%.4f", x[i].real);

        if (x[i].img >= 0.0001)

            printf("+%.4fj\n", x[i].img);

        else if (fabs(x[i].img) < 0.0001)

            printf("\n");

        else

            printf("%.4fj\n", x[i].img);

    }

}

void add(complex a, complex b, complex * c)

{

    c - > real = a.real + b.real;

    c - > img = a.img + b.img;

}

void mul(complex a, complex b, complex * c)

{

    c - > real = a.real * b.real - a.img * b.img;

    c - > img = a.real * b.img + a.img * b.real;

}

void sub(complex a, complex b, complex * c)

{

    c - > real = a.real - b.real;

    c - > img = a.img - b.img;

}

void divi(complex a, complex b, complex * c)

{

    c - > real = (a.real * b.real + a.img * b.img) / (

        b.real * b.real + b.img * b.img);

    c - > img = (a.img * b.real - a.real * b.img) / (b.real * b.real + b.img * b.img);

}


使用特权

评论回复
沙发
wowu| | 2023-4-13 17:31 | 只看该作者
FFT(Fast Fourier Transformation),即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的

使用特权

评论回复
板凳
tpgf| | 2023-4-14 09:20 | 只看该作者
想要看懂这个代码 就得懂傅里叶变换 就得明白复数是什么

使用特权

评论回复
地板
xiaoqizi| | 2023-4-14 11:10 | 只看该作者
在这个过程中我们如何解决复数运算的问题呢

使用特权

评论回复
5
木木guainv| | 2023-4-14 11:30 | 只看该作者
FFT算法是把长序列的DFT逐次分解为较短序列的DFT

使用特权

评论回复
6
磨砂| | 2023-4-14 12:04 | 只看该作者
FFT即为快速傅里叶变换,是离散傅里叶变换的快速算法,它是根据离散傅里叶变换的奇、偶、虚、实等特性,对离散傅里叶变换的算法进行改进获得的

使用特权

评论回复
7
晓伍| | 2023-4-14 12:19 | 只看该作者
FFT算法按照抽取方式的不同可分为DIT-FFT(按时间抽取)和DIF-FFT(按频率抽取)算法

使用特权

评论回复
8
abotomson| | 2023-5-11 15:25 | 只看该作者
二维FFT相当于对行和列分别进行一维FFT运算?

使用特权

评论回复
9
mickit| | 2023-5-11 16:21 | 只看该作者
MATLAB和Python等科学计算工具中都包括了FFT相关的库函数

使用特权

评论回复
10
jimmhu| | 2023-5-11 16:52 | 只看该作者
如何用C语言或汇编语言实现FFT(快速傅里叶)变换,

使用特权

评论回复
11
lihuami| | 2023-5-11 17:39 | 只看该作者
实现FFT需要了解FFT算法原理,以及掌握C语言的相关编程技巧。

使用特权

评论回复
12
sdCAD| | 2023-5-11 18:57 | 只看该作者
C语言中有一些现成的FFT库函数,例如FFTW、PFFFT等。使用这些库函数可以更方便地实现FFT操作,而且通常具有较高的精度和效率。

使用特权

评论回复
13
averyleigh| | 2023-5-11 19:18 | 只看该作者
如果想要深入学习FFT算法或者需要对FFT算法进行优化,则可以手动编写FFT代码。FFT算法包括Cooley-Tukey算法、Radix-2算法等,可以根据具体情况进行选择

使用特权

评论回复
14
kkzz| | 2023-5-11 19:35 | 只看该作者
用C语言实现FFT算法,还要做频谱分析

使用特权

评论回复
15
fengm| | 2023-5-11 20:41 | 只看该作者
想用C语言实现一个1024点的FFT

使用特权

评论回复
16
jimmhu| | 2023-5-11 20:53 | 只看该作者
傅里叶变换用C语言程序怎么实现?

使用特权

评论回复
17
youtome| | 2023-5-11 21:03 | 只看该作者
FFT的最优算法是什么?              

使用特权

评论回复
18
qiufengsd| | 2023-5-11 22:05 | 只看该作者
使用现成的库函数,可以快速实现FFT操作。

使用特权

评论回复
19
理想阳| | 2023-8-10 09:37 | 只看该作者
要实现FFT需要了解FFT算法的原理,并掌握c语言的编程技巧。

使用特权

评论回复
20
LinkMe| | 2023-8-10 09:49 | 只看该作者
二维FFT分别相当于一维FFT的行和列计算?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

2583

帖子

2

粉丝