【问题标题】:Different FFT results from Matlab fft and Objective-c fftMatlab fft和Objective-c fft的不同FFT结果
【发布时间】:2017-09-28 12:28:33
【问题描述】:

这是我在 matlab 中的代码:

x = [1 2 3 4];
result = fft(x);
a = real(result);
b = imag(result);

matlab 的结果:

a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]

还有我在 Objective-c 中的可运行代码:

int length = 4;
float* x =  (float *)malloc(sizeof(float) * length);
x[0] = 1;
x[1] = 2;
x[2] = 3;
x[3] = 4;

// Setup the length
vDSP_Length log2n = log2f(length);

// Calculate the weights array. This is a one-off operation.
FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);

// For an FFT, numSamples must be a power of 2, i.e. is always even
int nOver2 = length/2;

// Define complex buffer
COMPLEX_SPLIT A;
A.realp = (float *) malloc(nOver2*sizeof(float));
A.imagp = (float *) malloc(nOver2*sizeof(float));

// Generate a split complex vector from the sample data
vDSP_ctoz((COMPLEX*)x, 2, &A, 1, nOver2);

// Perform a forward FFT using fftSetup and A
vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);

//Take the fft and scale appropriately
Float32 mFFTNormFactor = 0.5;
vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, nOver2);
vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, nOver2);

printf("After FFT: \n");
printf("%.2f | %.2f \n",A.realp[0], 0.0);
for (int i = 1; i< nOver2; i++) {
    printf("%.2f | %.2f \n",A.realp[i], A.imagp[i]);
}
printf("%.2f | %.2f \n",A.imagp[0], 0.0);

目标 c 的输出:

   After FFT: 
   10.0 |  0.0
   -2.0 |  2.0

结果非常接近。我想知道其余的在哪里?我知道错过了什么,但不知道是什么。

更新:我找到了另一个答案 here 。我更新了输出

   After FFT: 
   10.0 |  0.0
   -2.0 |  2.0
   -2.0 |  0.0

但即使如此,仍然缺少 1 个元素 -2.0 | -2.0

【问题讨论】:

  • 您的打印循环仅打印第一个 nOver2 元素,在这种情况下为 2...您是否打算将循环绑定为 length
  • 是的。他们都是零
  • 在 Objective C 案例中,您正在执行一个实数到复数 FFT - 您可以使用复共轭对称性来填充缺失值。
  • @PaulR 你能告诉我怎么做吗?我在互联网上找不到任何样本

标签: objective-c matlab signal-processing fft


【解决方案1】:

执行 FFT 可提供右手频谱和左手频谱。 如果您有 N 个样本,您将返回的频率为:

( -f(N/2), -f(N/2-1), ... -f(1), f(0), f(1), f(2), ..., f(N/2-1) )

如果 A(f(i)) 是频率分量 f(i) 的复振幅 A,则以下关系成立:

Real{A(f(i)} = Real{A(-f(i))}   and Imag{A(f(i)} = -Imag{A(-f(i))}

这意味着,右手谱和左手谱的信息是相同的。但是虚部的符号不同。

Matlab 以不同的顺序返回频率。 Matlab命令是:

( f(0), f(1), f(2), ..., f(N/2-1) -f(N/2), -f(N/2-1), ... -f(1), )

要获得高阶,请使用 Matlab 函数 fftshift()。

如果您在 Matlab 中获得了 4 个样本:

a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]

这意味着:

A(f(0)) = 10 (DC value)
A(f(1)) = -2 + 2i (first frequency component of the right hand spectrum)
A(-f(2) = -2      ( second frequency component of the left hand spectrum)
A(-f(1) = -2 - 2i ( first frequency component of the left hand spectrum)

我不明白你的 Objective-C 代码。 但是,在我看来,该程序仅返回右手频谱。 所以一切都是完美的。

【讨论】:

  • A(f(1)) = -2 + 2i ->A(-f(1) = 2 + 2i 不是A(-f(1) = -2 - 2i 我说对了吗?
  • 是的,你做到了。幅度的实部相同,虚部的符号不同。
  • 所以 A(-f(1)) = 2 + 2i = -2 - 2i ?
  • 示例:A(+10kHz) = -2 + 2i; A(-10kHz) = -2 -2i
猜你喜欢
  • 2015-11-16
  • 1970-01-01
  • 2017-11-09
  • 2018-09-05
  • 2022-01-07
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多