打印
[开发工具]

C语言实现FFT算法

[复制链接]
7073|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aspoke|  楼主 | 2023-2-23 09:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define N 8

/*复数结构体类型*/
typedef struct{
double realPart;
double imaginaryPart;
}complexNumber;

complexNumber x[N], W[N/2]; //序列数组以及旋转因子数组
int size_x=N;
double PI=atan(1)*4;        //圆周率
void fastFourierOperation();//快速傅里叶变换算法
void initRotationFactor();  //生成旋转因子数组
void changePosition();      //偶奇变换算法
void outputArray();         //遍历输出数组
void add(complexNumber ,complexNumber ,complexNumber*); //复数加法
void mul(complexNumber ,complexNumber ,complexNumber*); //复数乘法
void sub(complexNumber ,complexNumber ,complexNumber*); //复数减法

/*长度为1024的冲激序列 */
void init1()               
{
        printf("Example:度为1024的冲激序列\n");
        x[0].realPart=1;
        x[0].imaginaryPart=0;
        for(int i=1;i<N;i++)
        {
                x[i].realPart=0;
                x[i].imaginaryPart=0;
        }
}

/*长度为1024的矩形序列 */
void init2()               
{               
        printf("Example:长度为1024的矩形序列\n");
        for(int i=0;i<N;i++)
        {
                x[i].realPart=1;
                x[i].imaginaryPart=0;
        }
}

/*长度为1024的sin[2πk/1024]序列 */
void init3()               
{            
        printf("Example:长度为1024的sin[2πk/1024]序列\n");
        for(int i=0;i<N;i++)
        {
                x[i].realPart=sin(2*PI*i/N);
                x[i].imaginaryPart=0;
        }
}

/*长度为1024的cos[2πk/1024]序列 */
void init4()              
{            
        printf("Example:长度为1024的cos[2πk/1024]序列\n");
        for(int i=0;i<N;i++)
        {
                x[i].realPart=cos(2*PI*i/N);
                x[i].imaginaryPart=0;
        }
}

int main()
{
    init3();               //调用不同的初始化函数,使用不同的例程进行测试
        printf("=============================================================================================================================================================================================\n");
        printf("输出原序列:\n");
        outputArray();
        initRotationFactor();  //生成旋转因子数组
        fastFourierOperation();//调用快速傅里叶变换
        printf("\n\n=============================================================================================================================================================================================\n");
        printf("输出FFT后的结果:\n");
        outputArray();         //遍历输出数组
        return 0;
}


/*快速傅里叶变换*/
void fastFourierOperation()
{
        int l=0;
        complexNumber up,down,product;
        changePosition();                            //偶奇变换算法
        for(int i=0;i<log(size_x)/log(2);i++)        //一级蝶形运算
        {   
                l=1<<i;
                for(int j=0;j<size_x;j+= 2*l )          //一组蝶形运算
                {            
                        for(int 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 initRotationFactor()
{
        for(int i=0;i<size_x/2;i++)
        {
                W[i].realPart=cos(2*PI/size_x*i);//用欧拉公式计算旋转因子
                W[i].imaginaryPart=-1*sin(2*PI/size_x*i);
        }
}


/*偶奇变换算法*/
void changePosition()      
{
        int j=0,k;//待会儿进行运算时需要用到的变量
        complexNumber temp;
        for (int i=0;i<size_x-1;i++)
        {
                if(i<j)
                {
                        //若倒序数大于顺序数,进行变址(换位);否则不变,防止重复交换,变回原数
                        temp=x[i];
                        x[i]=x[j];
                        x[j]=temp;
                }
                k=size_x/2;    //判断j的最高位是否为0
                while(j>=k)
                {              //最高位为1
                        j=j-k;
                        k=k/2;
                }
                j=j+k;        //最高位为0
        }
        printf("\n\n=============================================================================================================================================================================================\n");
        printf("输出倒序后的结果:\n");
        outputArray();
}


/*遍历输出数组*/
void outputArray()
{
        int num=0;
        for(int i=0;i<size_x;i++)
        {               
       
                if(x[i].imaginaryPart<0)
                {
                        printf("%.4f-j%.4f     ",x[i].realPart,fabs(x[i].imaginaryPart));
                }
                else
                {
                        printf("%.4f+j%.4f     ",x[i].realPart,x[i].imaginaryPart);
                }
                num++;
                if(num==10){
                        printf("\n");
                        num=0;
                }
        }
}


/*复数加法的定义*/
void add(complexNumber a,complexNumber b,complexNumber *c)
{
        c->realPart=a.realPart+b.realPart;
        c->imaginaryPart=a.imaginaryPart+b.imaginaryPart;
}

/*复数乘法的定义*/
void mul(complexNumber a,complexNumber b,complexNumber *c)
{
        c->realPart=a.realPart*b.realPart - a.imaginaryPart*b.imaginaryPart;
        c->imaginaryPart=a.realPart*b.imaginaryPart + a.imaginaryPart*b.realPart;
}

/*复数减法的定义*/
void sub(complexNumber a,complexNumber b,complexNumber *c)
{
        c->realPart=a.realPart-b.realPart;
        c->imaginaryPart=a.imaginaryPart-b.imaginaryPart;
}


使用特权

评论回复
沙发
hearstnorman323| | 2023-3-2 11:12 | 只看该作者
FFT的最优算法是什么?              

使用特权

评论回复
板凳
1988020566| | 2023-3-2 11:27 | 只看该作者
如何调用FFT32汇编程序实现

使用特权

评论回复
地板
tabmone| | 2023-3-2 11:39 | 只看该作者
怎么利用FFT算法对音频噪声进行处理

使用特权

评论回复
5
lzbf| | 2023-3-2 11:59 | 只看该作者
为什么FFT算法能够降低DFT的复杂度

使用特权

评论回复
6
usysm| | 2023-3-3 22:13 | 只看该作者
如何用FFT算法转换成相位差               

使用特权

评论回复
7
pentruman| | 2023-3-4 21:06 | 只看该作者
为什么用C语言的FFT算法后,结果都溢出了

使用特权

评论回复
8
alvpeg| | 2023-3-5 10:30 | 只看该作者
为什么用C语言的FFT算法后,结果都溢出了

使用特权

评论回复
9
plsbackup| | 2023-3-9 13:17 | 只看该作者
为什么用C语言的FFT算法后,结果都溢出了

使用特权

评论回复
10
yorkbarney| | 2023-3-9 13:28 | 只看该作者
C语言的fft和ifft程序工程文件,能共享一下吗?

使用特权

评论回复
11
modesty3jonah| | 2023-3-10 10:11 | 只看该作者
求FFT的C语言实现                 

使用特权

评论回复
12
hearstnorman323| | 2023-3-10 10:36 | 只看该作者
fft函数返回值是什么               

使用特权

评论回复
13
averyleigh| | 2023-3-10 10:52 | 只看该作者
信号处理有哪些算法可以实现?              

使用特权

评论回复
14
ulystronglll| | 2023-3-10 10:56 | 只看该作者
FFT运算就是快速傅里叶变换              

使用特权

评论回复
15
mmbs| | 2023-3-10 11:19 | 只看该作者
二阶滤波器用C语言怎么写              

使用特权

评论回复
16
lihuami| | 2023-3-10 11:23 | 只看该作者
在学信号系统,还没学到离散傅里叶变

使用特权

评论回复
17
febgxu| | 2023-3-10 13:08 | 只看该作者
如何用FFT得到谐波幅值频率和相位

使用特权

评论回复
18
louliana| | 2023-3-10 13:14 | 只看该作者
有谁用C语言实现过correl函数吗

使用特权

评论回复
19
robincotton| | 2023-3-10 13:50 | 只看该作者
FFT的最优算法是什么?              

使用特权

评论回复
20
houjiakai| | 2023-3-10 13:57 | 只看该作者
有用C语言实现的互相关算法的源代码吗

使用特权

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

本版积分规则

25

主题

2474

帖子

1

粉丝