【问题标题】:How to compare Real Fourier Transform implementation from Numerical Recipes to Matlab fft?如何比较从数值配方到 Matlab fft 的真实傅里叶变换实现?
【发布时间】:2016-10-31 11:27:35
【问题描述】:

我正在使用数值配方和(确认结果)Matlab 计算离散傅立叶变换。仅使用真实值。

我的 Matlab 代码

in(1)=0.0;
in(2)=1.0;
in(3)=2.0;
in(4)=3.0;
in(5)=4.0;
in(6)=5.0;
in(7)=6.0;
in(8)=7.0;

out = fft(in);

给我

out =
 28.0000 + 0.0000i
 -4.0000 + 9.6569i
 -4.0000 + 4.0000i
 -4.0000 + 1.6569i
 -4.0000 + 0.0000i
 -4.0000 - 1.6569i
 -4.0000 - 4.0000i
 -4.0000 - 9.6569i

我需要将data 输入的内容发送到数字食谱

void realft( float data[], unsigned long n, int isign ){...}

为了得到与 Matlab 相同的输出?

从这个NR forum链接,我发现realft的输入需要移动一个位置,所以我使用in[0] = 0,因此输入比N大1个元素。

测试代码:

#include <stdio.h>
#define LEN 8
int main()
{
  float inout[LEN+1];

  inout[0] = 0.0;
  inout[1] = 0.0;
  inout[2] = 1.0;
  inout[3] = 2.0;
  inout[4] = 3.0;
  inout[5] = 4.0;
  inout[6] = 5.0;
  inout[7] = 6.0;
  inout[8] = 7.0;

  realft( inout, LEN, 1 );

  for( unsigned int i=0; i<LEN+1; i=i+1)
      printf("%15.10f \n",inout[i]);

  return 0;
}

测试代码的输出是:

 0.00000000 
28.00000000
-4.00000000
-4.00000000 
-9.65685463
-4.00000000
-4.00000000
-4.00000000
-1.65685427

与 Matlab 类似,但不同。

realft 取自 Numerical Recipes(使用 four1 例程):

【问题讨论】:

  • 有什么不同?给我们看minimal reproducible example
  • 已编辑,看看。
  • 再次编辑,由于可能存在版权问题,删除了代码。

标签: c signal-processing fft


【解决方案1】:

Matlab 和 Numerical Recipes 的实现之间的第一个不同之处在于,除了您已经注意到并考虑到的逐一索引之外,它们基于 FFT 的稍微不同的定义。更具体地说,Matlab uses a negative complex exponential for the forward transform 而 Numerical Recipes 使用正复指数。相应地,Numerical Recipes 的实现将给出一个结果,它是 Matlab 的复共轭。

另一件事是,这些实现会以不同的打包顺序产生结果,而 Numerical Recipes 的实现仅输出频谱的非冗余下半部分。从图形上看,这个映射可以用下图表示(在根据前一点关于复共轭改变虚部的符号之后):

【讨论】:

  • 是否可以简单地更改 NR 算法以提供与 Matlab 相同的非复共轭结果?
  • 这也能解释为什么数字配方和 FFTW 之间的复杂结果有相反的符号吗?
  • @benrules2 是的,Matlab 和 FFTW 使用基本相同的定义(除了基于 0 和 1 的索引约定)
  • 感谢您的回复!如果您不介意,请跟进 Q... 使用负复指数或正复指数是否有任何意义,或者它只是您必须遵守的约定?
  • @benrules2 只是约定俗成的问题
【解决方案2】:

我认为你需要参考 realft() 的源代码。使用此功能似乎有问题。原因是,虽然输入是实数值,但频谱的数值通常很复杂。但是,在您的程序中,结果是从原始 inout 返回的,它是实数数据类型,而虚部被丢弃。

【讨论】:

    【解决方案3】:

    对于这两个示例,您有不同的输入(相似但不同)。对于 matlab 示例,您的输入是从 0->7 (含)的斜坡。但是由于索引差异(其他人提到),在 C 实现中,您的输入是 0,0,1,2,3,4,5,6(而不是 0,1,2,3,4 ,5,6,7)。如果对C做一堆matlab,数组索引的区别(matlab从1开始,C从0开始)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多