如何比较从数值食谱到 Matlab fft 的实傅里叶变换实现?
How to compare Real Fourier Transform implementation from Numerical Recipes to Matlab fft?
我正在使用 Numerical Recipes 和(为了确认结果)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 forumlink,我发现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
例程):
Matlab 和 Numerical Recipes 的实现之间的第一个不同之处在于,除了您已经注意到并说明的逐一索引之外,它们基于稍微不同的定义快速傅立叶变换。更具体地说,Matlab uses a negative complex exponential for the forward transform 而 Numerical Recipes 使用正复指数。相应地,Numerical Recipes 的实现将给出一个结果,该结果是来自 Matlab 的结果的复共轭。
另一件事是这些实现以不同的打包顺序产生结果,而 Numerical Recipes 的实现仅输出非冗余的下半部分频谱。在图形上,这个映射可以用下图表示(在根据关于复共轭的前一点改变虚部的符号之后):
我觉得你需要参考一下realft()的源码。好像使用这个函数有问题。原因是,虽然输入是实数值,但频谱的值通常很复杂。但是,在您的程序中,结果是从原始数据类型的 inout 返回的,并且虚部被丢弃。
对于这两个示例,您有不同的输入(相似但不同)。对于 matlab 示例,您的输入是从 0->7(含)的斜坡。但是由于索引差异(其他人提到),在 C 实现中,您的输入是 0,0,1,2,3,4,5,6(而不是 0,1,2,3,4 ,5,6,7).如果你是做一堆matlab转C,数组索引的区别(matlab从1开始,C从0开始)。
我正在使用 Numerical Recipes 和(为了确认结果)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 forumlink,我发现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
例程):
Matlab 和 Numerical Recipes 的实现之间的第一个不同之处在于,除了您已经注意到并说明的逐一索引之外,它们基于稍微不同的定义快速傅立叶变换。更具体地说,Matlab uses a negative complex exponential for the forward transform 而 Numerical Recipes 使用正复指数。相应地,Numerical Recipes 的实现将给出一个结果,该结果是来自 Matlab 的结果的复共轭。
另一件事是这些实现以不同的打包顺序产生结果,而 Numerical Recipes 的实现仅输出非冗余的下半部分频谱。在图形上,这个映射可以用下图表示(在根据关于复共轭的前一点改变虚部的符号之后):
我觉得你需要参考一下realft()的源码。好像使用这个函数有问题。原因是,虽然输入是实数值,但频谱的值通常很复杂。但是,在您的程序中,结果是从原始数据类型的 inout 返回的,并且虚部被丢弃。
对于这两个示例,您有不同的输入(相似但不同)。对于 matlab 示例,您的输入是从 0->7(含)的斜坡。但是由于索引差异(其他人提到),在 C 实现中,您的输入是 0,0,1,2,3,4,5,6(而不是 0,1,2,3,4 ,5,6,7).如果你是做一堆matlab转C,数组索引的区别(matlab从1开始,C从0开始)。