在任何频率计算傅里叶变换

3

我知道,如果我们有一些代表某种波的数据,例如图像线值,我们可以使用傅里叶变换来获取该波的频率函数。但是我们在点x=0...N-1处有N个值,而且我们只在输出处得到了N个频率。因此,我想在范围[0,N-1]中的任何位置分析该波,例如在u = 1.5点。我该怎么做?


1
你应该在mathoverflow.com上提问。 - Michael Bray
5
在mathoverflow的常见问题解答中很清楚地指出,这不是该论坛的好问题。似乎程序员想问的任何数学问题都没有合适的地方。 - user66363
那么你的意思是我在那里得到相同的答案吗? - maximus
只要我们不涉及实现和快速算法,这与编程实际上并没有关系。但它在信号分析中很有用,这就是我为什么问这个问题的原因,但我也在思考是否足够好以在这里提出这个问题。 - maximus
这个问题现在已经在MathOverflow上提出了:http://mathoverflow.net/questions/11537/calculating-fourier-transform-at-any-frequency,似乎吸引了更好的回答。 - Jason Orendorff
3个回答

4

从一组样本中计算任何频率的傅里叶变换值其实非常容易:

F(w)= sum[over all sample indices k] ( f(t_k) e^(i w t_k) )

从代码层面来说,你可以这样做:

float Fourier(float omega) {
  Complex a(0.0); // think "a is for accumulator"
  for(int k=0; k<value.size(); ++k) {
    float time= t_start + k*dt;
    float theta= omega * time;  // this is (w t_k) from above
    a+= value[k] * Complex(cos(theta), sin(theta));
  }
  return a;
} // note, I have explicitly written out e^(i theta) = cos(theta) + i sin(theta)

如果您有不规则的采样时间,可以使用一个时间[]向量/数组和您的value[]向量/数组,而不是从索引计算时间。(但是,要小心,因为不规则间隔的样本并不一定意味着您认为的那样!如果这个评论在任何方面都很神秘,请坚持使用常规样本...)唯一的问题是,如果您想基于常规样本生成N个等间隔频率,用上述方法将需要O(N^2)的时间。快速傅里叶变换是一种能够以O(N log N)的时间进行此操作的算法。

抱歉,我不理解。我们有一个函数f(t),并且我们知道它在t = 0..N-1的点上的值。x_k = f(t_k),其中t_k = k。因此,我们有一个离散傅里叶变换:X_k = sum[over all sample indices n] (x_n * e^(-(k*n)i2Pi/N))从这个方程中,我们可以看出FT只有N个点: X_k,k = 0..N-1我认为你写的是连续情况的方程。或者我理解错了什么? - maximus
我为连续频率编写了一个方程——我认为这就是你想要的。输入样本是离散的并不重要;在数学上,你将它们视为脉冲,将它们插入方程中并计算结果。如果样本是等间距的,则上述公式和计算可为你提供FFT计算出的频率之间的完美自然插值。 - comingstorm
有趣的...我会去看看!谢谢你的想法) - maximus
区别在于,您建议的定期间隔频率(由FFT计算)适用于重复样本 - 就像您将样本包装成无限重复循环一样。这对于任意/连续频率没有意义;对于这种情况,最好将您的(有限)样本集视为唯一发生 - 要么是孤立的,要么是(等效地)被无限数量的零样本包围... - comingstorm

1

你需要插值这些中间点的数据。


这是我一开始想的。但是还有其他解决这个问题的方法吗? - maximus
从根本上讲,不需要。当然,您可以改变主意并决定不在中间点分析数据,在这种情况下,您就不需要插值。 - janneb
你必须进行插值 - 但结果只是一个“有根据的猜测”。为了在频域中获得更好的分辨率,你还需要在时间域中获取更多的样本。 - peterchen
@peterchen:当然可以。不用说,插值不能神奇地创造以前不存在的数据。 - janneb

0

距离我上次做这些已经超过10年了,但我想Matlab有一些傅里叶变换的方法可以让你做你想要的事情。至少在我们的线性信号和DSP课程中就是这样使用的。


如果它们已知,我希望在C语言中实现它们。 - maximus
你是想为了自己的利益来实现它们,还是因为你需要使用它们?http://www.fftw.org/提供了一个用于C语言中傅里叶变换的库。 - taylonr
我需要它,不是为了自己的利益。谢谢! - maximus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接