Matlab FFT 和自制 FFT

2023-12-13

我正在尝试验证我应该用于项目的 FFT 算法与 Matlab 上的相同算法。 关键是,使用我自己的 C FFT 函数,我总是得到在 Matlab 中评估的双面 FFT 频谱的正确(第二个)部分,而不是“预期”的第一个部分。

例如,如果我的第三个 bin 的形式为 a+i*b,则 Matlab FFT 的第三个 bin 为 a-i*b。 A 和 b 值相同,但我总是得到 Matlab 的复共轭。 我知道就幅度和功率而言没有问题(导致绝对值),但我想知道就相位而言我是否会读取总是错误的角度。

我对Matlab不太熟练,不知道(而且我没有在网上找到有用的信息)Matlab FFT是否可能首先返回负频率然后正频率的FFT幽灵......或者如果我必须修复我的FFT算法......或者如果一切正常,因为无论 FFT 的哪个部分我们选择作为单边频谱,相位都保持不变(但我对最后一个选项表示怀疑)。

Example:

如果S是N=512个样本的样本数组,Matlab中的Y = fft(S)返回FFT为(数组前半部分的虚部符号是随机的,只是为了显示复共轭差第二部分):

1   A1    +  i*B1     (DC, B1 is always zero)
2   A2    +  i*B2
3   A3    -  i*B3
4   A4    +  i*B4
5   A5    +  i*B5
...
253 A253  -  i*B253
254 A254  +  i*B254
255 A255  +  i*B255
256 A256  +  i*B256
257 A257  -  i*B257   (Nyquyst, B257 is always zero)
258 A256  -  i*B256
259 A255  -  i*B255
260 A254  -  i*B254
261 A253  +  i*B253
...
509 A5    -  i*B5
510 A4    -  i*B4
511 A3    +  i*B3
512 A2    -  i*B2

我的 FFT 实现仅在 Y 数组中返回 256 个值(这没问题),如下所示:

1   1    A1    +  i*B1     (A1 is the DC, B1 is Nyquist, both are pure Real numbers)
2   512  A2    -  i*B2
3   511  A3    +  i*B3
4   510  A4    -  i*B4
5   509  A5    +  i*B5
...
253 261  A253  +  i*B253
254 260  A254  -  i*B254
255 259  A255  -  i*B255
256 258  A256  -  i*B256

其中第一列是 Y 数组的正确索引,第二列只是 Matlab FFT 实现中相对行的引用。

正如你所看到的,我的 FFT 实现(除了 DC)返回的 FFT 就像下半部分一样 Matlab 的 FFT(按相反顺序)。

总结一下:即使我按照建议使用 fftshift,似乎我的实现总是回来Matlab FFT 中的什么应该被认为是消极部分的频谱。 错误在哪里???

这是我使用的代码:

注 1:此处未声明 FFT 数组,而是在函数内部更改。最初它保存了 N 个样本(real值)和在最后它包含单边 FFT 频谱的 N/2 +1 个 bin。

注 2:N/2+1 个 bin 存储在 N/2 个元素中,只是因为 DC 分量始终是实数(并且存储在 FFT[0] 中),而且 Nyquyst(它存储在 FFT[1] 中) ),这个例外除了所有其他偶数元素 K 持有实数,而烤箱元素 K+1 持有虚数部分。

void Fft::FastFourierTransform( bool inverseFft ) {
   double twr, twi, twpr, twpi, twtemp, ttheta;
   int i, i1, i2, i3, i4, c1, c2;
   double h1r, h1i, h2r, h2i, wrs, wis;
   int nn, ii, jj, n, mmax, m, j, istep, isign;
   double wtemp, wr, wpr, wpi, wi;    
   double theta, tempr, tempi;

   // NS is the number of samples and it must be a power of two
   if( NS == 1 )
      return;

   if( !inverseFft ) {
      ttheta = 2.0 * PI / NS;
      c1 = 0.5;
      c2 = -0.5;
   }
   else {
      ttheta = 2.0 * PI / NS;
      c1 = 0.5;
      c2 = 0.5;
      ttheta = -ttheta;
      twpr = -2.0 * Pow( Sin( 0.5 * ttheta ), 2 );
      twpi = Sin(ttheta);
      twr = 1.0+twpr;
      twi = twpi;
      for( i = 2; i <= NS/4+1; i++ ) {
         i1 = i+i-2;
         i2 = i1+1;
         i3 = NS+1-i2;
         i4 = i3+1;
         wrs = twr;
         wis = twi;
         h1r = c1*(FFT[i1]+FFT[i3]);
         h1i = c1*(FFT[i2]-FFT[i4]);
         h2r = -c2*(FFT[i2]+FFT[i4]);
         h2i = c2*(FFT[i1]-FFT[i3]);
         FFT[i1] = h1r+wrs*h2r-wis*h2i;
         FFT[i2] = h1i+wrs*h2i+wis*h2r;
         FFT[i3] = h1r-wrs*h2r+wis*h2i;
         FFT[i4] = -h1i+wrs*h2i+wis*h2r;
         twtemp = twr;
         twr = twr*twpr-twi*twpi+twr;
         twi = twi*twpr+twtemp*twpi+twi;
      }
      h1r = FFT[0];
      FFT[0] = c1*(h1r+FFT[1]);
      FFT[1] = c1*(h1r-FFT[1]);
   }
   if( inverseFft )
      isign = -1;
   else
      isign = 1;
   n = NS;
   nn = NS/2;
   j = 1;
   for(ii = 1; ii <= nn; ii++) {
      i = 2*ii-1;
      if( j>i ) {
         tempr = FFT[j-1];
         tempi = FFT[j];
         FFT[j-1] = FFT[i-1];
         FFT[j] = FFT[i];
         FFT[i-1] = tempr;
         FFT[i] = tempi;
      }
      m = n/2;
      while( m>=2 && j>m ) {
         j = j-m;
         m = m/2;
      }
      j = j+m;
   }
   mmax = 2;
   while(n>mmax) {
      istep = 2*mmax;
      theta = 2.0 * PI /(isign*mmax);
      wpr = -2.0 * Pow( Sin( 0.5 * theta ), 2 );
      wpi = Sin(theta);
      wr = 1.0;
      wi = 0.0;
      for(ii = 1; ii <= mmax/2; ii++) {
         m = 2*ii-1;
         for(jj = 0; jj <= (n-m)/istep; jj++) {
            i = m+jj*istep;
            j = i+mmax;
            tempr = wr*FFT[j-1]-wi*FFT[j];
            tempi = wr*FFT[j]+wi*FFT[j-1];
            FFT[j-1] = FFT[i-1]-tempr;
            FFT[j] = FFT[i]-tempi;
            FFT[i-1] = FFT[i-1]+tempr;
            FFT[i] = FFT[i]+tempi;
         }
         wtemp = wr;
         wr = wr*wpr-wi*wpi+wr;
         wi = wi*wpr+wtemp*wpi+wi;
      }
      mmax = istep;
   }
   if( inverseFft )
      for(i = 1; i <= 2*nn; i++)
         FFT[i-1] = FFT[i-1]/nn;
   if( !inverseFft ) {
      twpr = -2.0 * Pow( Sin( 0.5 * ttheta ), 2 );
      twpi = Sin(ttheta);
      twr = 1.0+twpr;
      twi = twpi;
      for(i = 2; i <= NS/4+1; i++) {
         i1 = i+i-2;
         i2 = i1+1;
         i3 = NS+1-i2;
         i4 = i3+1;
         wrs = twr;
         wis = twi;
         h1r = c1*(FFT[i1]+FFT[i3]);
         h1i = c1*(FFT[i2]-FFT[i4]);
         h2r = -c2*(FFT[i2]+FFT[i4]);
         h2i = c2*(FFT[i1]-FFT[i3]);
         FFT[i1] = h1r+wrs*h2r-wis*h2i;
         FFT[i2] = h1i+wrs*h2i+wis*h2r;
         FFT[i3] = h1r-wrs*h2r+wis*h2i;
         FFT[i4] = -h1i+wrs*h2i+wis*h2r;
         twtemp = twr;
         twr = twr*twpr-twi*twpi+twr;
         twi = twi*twpr+twtemp*twpi+twi;
      }
      h1r = FFT[0];
      FFT[0] = h1r+FFT[1];  // DC
      FFT[1] = h1r-FFT[1];  // FS/2 (NYQUIST)
   }            
   return;
}

在 matlab 中尝试使用 fftshift(fft(...))。 Matlab 在调用 FFT 后不会自动移动频谱,这就是他们实现 fftshift() 函数的原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Matlab FFT 和自制 FFT 的相关文章

  • 使用 python 在网络上部署 matlab 应用程序

    您好 我想使用 python 在网络上部署 matlab 应用程序 有没有办法做到这一点 我已按照数学工作网站上的文档将我的应用程序转换为 jar 文件 java 类 有人能指出我前进的正确方向吗 事实上 您的 Matlab 代码打包为 J
  • 如何选择部分密集数据集的均匀分布子集?

    P是一个 n d 矩阵 持有nd 维样本 P某些地区的密度是其他地区的几倍 我想选择一个子集P其中任意样本对之间的距离大于d0 并且我需要将其传播到整个区域 所有样本都具有相同的优先级 无需优化任何内容 例如覆盖面积或成对距离之和 这是执行
  • 在 MATLAB 中将数据拟合到 B 样条

    我正在尝试估计矩阵形式的时间序列数据中的缺失值 列代表时间点 即现在 我想将矩阵的每一行拟合到 B 样条曲线 并用它来估计缺失值 我可以使用 MATLAB 将数据拟合到普通样条曲线 但我完全陷入尝试找出如何拟合数据以创建 B 样条曲线的困境
  • 如何读取 10 位原始图像?其中包含 RGB-IR 数据

    我想知道如何从我的 10 位原始 它有 rgb ir 图像数据 数据中提取 RGB 图像 如何使用 Python 或 MATLAB 进行阅读 拍摄时的相机分辨率为 1280x720 室内照片图片下载 https drive google c
  • 类方法的自定义代码完成?

    在 MATLAB 中 可以定义代码建议和完成 如标题为 的文档页面中所述 自定义代码建议和完成 https www mathworks com help matlab matlab prog customize code suggestio
  • 在 Matlab 中快速加载大块二进制文件

    我有一些相当大的 int16 格式的数据文件 256 个通道 大约 75 1 亿个样本 每个文件约 40 50 GB 左右 它以平面二进制格式编写 因此结构类似于 CH1S1 CH2S1 CH3S1 CH256S1 CH1S2 CH2S2
  • 是否有一个函数可以检查矩阵是否对角占优(行占优)

    矩阵是对角占优 http en wikipedia org wiki Diagonally dominant matrix 按行 如果对角线处的值在绝对意义上大于该行中所有其他绝对值的总和 对于列也是如此 只是相反 matlab中有没有函数
  • 整数的十进制表示形式中的分隔数字

    例如 我想将用户输入作为整数输入 45697 并将前两位数字存储在数组 向量或其他内容中 例如 4 5 6 9 7 这样我就可以使用一些函数调用来检查前两个值 4 5 并对它们进行计算 问题 我不知道如何存储恢复前两个值 有没有简单的函数调
  • 优化 MATLAB 代码(嵌套 for 循环计算相似度矩阵)

    我正在 MATLAB 中基于欧几里德距离计算相似度矩阵 我的代码如下 for i 1 N M N is the size of the matrix x for whose elements I am computing similarit
  • 从 Java 运行 MATLAB 函数

    我在 MATLAB 中有一个 m 文件 我想从 Java 调用该文件 并以字符串或 Java 中的任何形式获取解决方案 这听起来很简单 但由于某种原因我无法让它发挥作用 我试过这个 matlab nosplash wait nodeskto
  • MATLAB - GUI 和 OPC 服务器

    我想在 MATLAB 中设计一个图形用户界面 可以使用 MATLAB 的过程控制对象链接和嵌入 OPC 工具箱连续读取数据 我怎样才能实现这个 我已经设计了图形用户界面 但我无法将数据读入图形用户界面 就这样做 type opctoolMA
  • 归一化互相关的基础知识

    我正在尝试使用范数校正2 归一化互相关 http en wikipedia org wiki Cross correlation Normalized cross correlation 来自 MATLAB 用于计算发育中胚胎中移动形状的速
  • 检查图像中是否有太薄的区域

    我正在尝试验证雕刻机的黑白图像 更多的是剪贴画图像 不是照片 我需要考虑的主要事情之一是区域的大小 或线条的宽度 因为机器无法处理太细的线条 所以我需要找到比给定阈值更细的区域 以此图为例 竖琴的琴弦可能太细而无法雕刻 我正在阅读有关 Ma
  • 动态调整自定义刻度数

    Taking SO 的一个例子 https stackoverflow com a 7139485 97160 我想根据当前视图调整轴刻度 这是默认行为 除非设置自定义的刻度数 下图展示了由此产生的行为 左侧是默认行为 右侧是带有自定义刻度
  • 在 Matlab 的命令窗口中获取旧式帮助

    问题的简短版本 在最新版本的 Matlab 中 我在 Windows 上的 R2014b 和 R2015a 中看到过 当您键入help foo你得到一个简要描述 简介函数及其签名 例如 输入help bsxfun产生类似这样的东西 只有更好
  • 如何在向量中的所有点之间绘制线?

    我有一个包含二维空间中一些点的向量 我希望 MATLAB 用从每个点到每个其他点绘制的线来绘制这些点 基本上 我想要一个所有顶点都连接的图 你能用情节来做到这一点吗 如果可以 怎么做 一种解决方案是使用该函数为每个点组合创建一组索引MESH
  • 如何使用Matlab将数据保存到Excel表格中?

    我想将数据以表格形式保存在 Excel 工作表中 它应该看起来像 Name Age R no Gpa Adnan 24 18 3 55 Ahmad 22 12 3 44 Usman 23 22 3 00 每次当我执行我的文件时类数据 m 下
  • 如何在Matlab中打印带有千位分隔符的整数?

    我想使用逗号作为千位分隔符将数字转换为字符串 就像是 x 120501231 21 str sprintf 0 0f x 但随着效果 str 120 501 231 21 如果内置fprintf sprintf做不到 我想可以使用正则表达式
  • 命令 A(~A) 在 matlab 中的真正作用是什么

    我一直在寻找找到矩阵非零最小值的最有效方法 并在论坛上找到了这个 设数据为矩阵A A A nan minNonZero min A 这是非常短且高效的 至少在代码行数方面 但我不明白当我们这样做时会发生什么 我找不到任何关于此的文档 因为它
  • Matlab:条形图中缺少标签

    使用 Matlab 2012 和 2013 我发现设置XTickLabel on a bar图表最多只能使用 15 个柱 如果条形较多 则标签会丢失 如下所示 绘制 15 个条形图 N 15 x 1 N labels num2str x d

随机推荐