上一个NB人写的 傅立叶变换和反变换

本文详细介绍了快速傅立叶变换(FFT)及其逆变换(IFFT)的实现方法。包括了复数定义、基本运算、FFT算法流程及IFFT算法流程等内容。适用于信号处理等领域。
部署运行你感兴趣的模型镜像

 
  //////////////////////////////////////////////////////////  
  //   internal   definitions  
   
  #define   PI   (double)3.14159265359  
   
  /*complex   number*/  
  typedef   struct  
  {  
  double   re;  
  double   im;  
  }COMPLEX;  
   
  /*complex   add*/  
  COMPLEX   Add(COMPLEX   c1,   COMPLEX   c2)  
  {  
  COMPLEX   c;  
  c.re=c1.re+c2.re;  
  c.im=c1.im+c2.im;  
  return   c;  
  }  
   
  /*complex   substract*/  
  COMPLEX   Sub(COMPLEX   c1,   COMPLEX   c2)  
  {  
  COMPLEX   c;  
  c.re=c1.re-c2.re;  
  c.im=c1.im-c2.im;  
  return   c;  
  }  
   
  /*complex   multiple*/  
  COMPLEX   Mul(COMPLEX   c1,   COMPLEX   c2)  
  {  
  COMPLEX   c;  
  c.re=c1.re*c2.re-c1.im*c2.im;  
  c.im=c1.re*c2.im+c2.re*c1.im;  
  return   c;  
  }  
  //////////////////////////////////////////////////////////  
   
   
   
  这是FFT/****************************************************  
  FFT()  
   
  参数:  
   
  TD为时域值  
  FD为频域值  
  power为2的幂数  
   
  返回值:  
   
  无  
   
  说明:  
   
  本函数实现快速傅立叶变换  
  ****************************************************/  
  void   FFT(COMPLEX   *   TD,   COMPLEX   *   FD,   int   power)  
  {  
  int   count;  
  int   i,j,k,bfsize,p;  
  double   angle;  
  COMPLEX   *W,*X1,*X2,*X;  
   
  /*计算傅立叶变换点数*/  
  count=1<<power;  
   
  /*分配运算所需存储器*/  
  W=(COMPLEX   *)malloc(sizeof(COMPLEX)*count/2);  
  X1=(COMPLEX   *)malloc(sizeof(COMPLEX)*count);  
  X2=(COMPLEX   *)malloc(sizeof(COMPLEX)*count);  
   
  /*计算加权系数*/  
  for(i=0;i<count/2;i++)  
  {  
  angle=-i*PI*2/count;  
  W[i].re=cos(angle);  
  W[i].im=sin(angle);  
  }  
   
  /*将时域点写入存储器*/  
  memcpy(X1,TD,sizeof(COMPLEX)*count);  
   
  /*蝶形运算*/  
  for(k=0;k<power;k++)  
  {  
  for(j=0;j<1<<k;j++)  
  {  
  bfsize=1<<(power-k);  
  for(i=0;i<bfsize/2;i++)  
  {  
  p=j*bfsize;  
  X2[i+p]=Add(X1[i+p],X1[i+p+bfsize/2]);  
  X2[i+p+bfsize/2]=Mul(Sub(X1[i+p],X1[i+p+bfsize/2]),W[i*(1<<k)]);  
  }  
  }  
  X=X1;  
  X1=X2;  
  X2=X;  
  }  
   
  /*重新排序*/  
  for(j=0;j<count;j++)  
  {  
  p=0;  
  for(i=0;i<power;i++)  
  {  
  if   (j&(1<<i))   p+=1<<(power-i-1);  
  }  
  FD[j]=X1[p];  
  }  
   
  /*释放存储器*/  
  free(W);  
  free(X1);  
  free(X2);  
  }  
   
   
  /****************************************************  
  IFFT()  
   
  参数:  
   
  FD为频域值  
  TD为时域值  
  power为2的幂数  
   
  返回值:  
   
  无  
   
  说明:  
   
  本函数利用快速傅立叶变换实现傅立叶反变换  
  ****************************************************/  
  void   IFFT(COMPLEX   *   FD,   COMPLEX   *   TD,   int   power)  
  {  
  int   i,   count;  
  COMPLEX   *x;  
   
  /*计算傅立叶反变换点数*/  
  count=1<<power;  
   
  /*分配运算所需存储器*/  
  x=(COMPLEX   *)malloc(sizeof(COMPLEX)*count);  
   
  /*将频域点写入存储器*/  
  memcpy(x,FD,sizeof(COMPLEX)*count);  
   
  /*求频域点的共轭*/  
  for(i=0;i<count;i++)  
  x[i].im   =   -x[i].im;  
   
  /*调用FFT*/  
  FFT(x,   TD,   power);  
   
  /*求时域点的共轭*/  
  for(i=0;i<count;i++)  
  {  
  TD[i].re   /=   count;  
  TD[i].im   =   -TD[i].im   /   count;  
  }  
   
  /*释放存储器*/  
  free(x);  
  }  

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

### A*B 快速傅里叶变换 (FFT) 算法实现与应用 #### FFT 基本原理 快速傅立叶变换(FFT)并不是一种新的变换,而是离散傅立叶变换(DFT)的一种高效算法。通过利用DFT中的对称性周期性特性,可以显著减少所需的计算量。对于长度为 \( N \) 的序列,传统DFT需要大约 \( 4N^2 \) 次实数乘法 \( 2N(2N-1) \) 次实数加法[^1]。 #### 复单位根的应用 在FFT中使用的复单位根 \( w \),即基向量的组合,在圆上表示。这些复单位根用于简化DFT矩阵的操作,从而提高效率。例如,在MATLAB中,`fft()` 函数就是基于这种优化后的快速傅立叶变换来执行实际的数据处理操作[^2]。 #### C语言实现A*B FFT算法 为了展示如何在一个具体的编程环境中实现两个数组\( A * B \)之间的卷积并通过FFT加速这一过程,下面给出一段简单的C代码: ```c #include <stdio.h> #include <complex.h> void fft(complex double x[], int n, int inv){ /* ...省略具体FFT逻辑... */ } // 卷积定理:conv(A,B)=ifft(fft(A).*fft(B)) void convolve_fft(const complex double a[], const complex double b[], size_t na, size_t nb, complex double result[]){ // 计算合适的FFT大小 int n = nextpow2(na + nb - 1); // 初始化并填充输入缓冲区 complex double fa[n], fb[n]; memset(fa, 0, sizeof(fa)); memcpy(fa, a, na * sizeof(a[0])); memset(fb, 0, sizeof(fb)); memcpy(fb, b, nb * sizeof(b[0])); // 执行前向FFT转换 fft(fa, n, 1); fft(fb, n, 1); // 将结果相乘 for(int i=0; i<n; ++i) fa[i] *= fb[i]; // 反向FFT得到最终结果 fft(fa, n, -1); for(size_t i=0; i<na+nb-1; ++i) result[i] = fa[i]/n; } ``` 此段代码展示了如何使用FFT来进行两组数据间的线性卷积运算。注意这里忽略了部分细节如内存分配错误检查以及更精确地确定所需的工作空间尺寸等问题。 #### 应用场景 FFT广泛应用于多个领域,特别是在涉及频域分析的任务中表现尤为突出。比如音频信号处理、图像压缩编码等方面都有其身影。另外,在通信工程里的调制解调技术也离不开它高效的谱估计能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值