来自 Matlab fft 和 Objective-c fft 的不同 FFT 结果
Different FFT results from Matlab fft and Objective-c fft
这是我在 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);
objective 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
执行 FFT 可提供右手频谱和左手频谱。
如果你有 N 个样本,你将 return 的频率是:
( -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 returns 不同顺序的频率。
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 代码。
然而,在我看来,程序 return 只是右手频谱。
所以任何事情都是完美的。
这是我在 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);
objective 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
执行 FFT 可提供右手频谱和左手频谱。 如果你有 N 个样本,你将 return 的频率是:
( -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 returns 不同顺序的频率。 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 代码。 然而,在我看来,程序 return 只是右手频谱。 所以任何事情都是完美的。