对称快速傅里叶变换

3
我在 R 中有一个名为 s 的向量,其中包含数值。我刚刚使用函数 fft(s) 计算了快速傅里叶变换。然后将这些值打印到图表中,如下: enter image description here 其中 x 是简单的 1, ... length(fft(s))。我看到这里有强烈的对称性——这是为什么?我原本期望像这样: enter image description here 我做错了什么?以下是第一个图表的 MWE:
df <- structure(list(value = c(3, 1537.68157138987, 531.727745627154, 
8.50387522397935, 5.40309722205537, 2.30232661295167, 0.420000953675226, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4.73469069995451, -829.997919240523, 
-3919.09161844073, -6460.79922752307, -6507.49592868557, -4849.27485532219, 
-1674.36434175734, -83.1428571428571, -2.55813257187214, -261.182084182236, 
-2915.2762208206, -5668.7235841082, -6990.36364128962, -6997.7273121356, 
-6211.86050115633, -4378.77236521268, -1421.9056880109, -30.3635181412285, 
-3.58181865471396, -2408.88296333223, -3106.95655095245, -6482.32762645408, 
-6111.41765122797, -1821.04333977064, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 41.499896933588, 998.907991416867, 3778.2752099702, 
6543, 7005.95412518948, 6995.72726353206, 6293.82005765438, 3269.99904633924, 
592.910420911179, 2, 1378.82116693398, 4391.17937491872, 6822.45459767001, 
6220.908446583, 3447.42762806772, 581, 10.2727745627154, 873.056274992053, 
3248.72737676457, 3776.64174236464, 3779.59937375451, 2711.30950879224
)), .Names = "value", row.names = c(NA, -182L), class = "data.frame")
fft_res <- fft(df$value)
ggplot(data.frame(x = 1:length(fft_res), value = Mod(fft_res)), aes(x,value)) + geom_line()

为什么要给负评? - Make42
@jogo:我添加了一个最小可行示例(MWE)。这样好吗? - Make42
如果你对一个实值函数应用FFT,你总是会得到一个对称的结果! - Ben Bolker
@BenBolker:我知道傅里叶变换的图形在坐标原点处是对称的。这是正在发生的事情吗?我只需要在绘图中使用值x=-0.5*length(fft_res):0.5*length(fft_res)吗?我以为fft(...)只返回正轴... - Make42
1个回答

3

对于应用于实值数据的FFT(fft()返回正频率和负频率的值),对称性是一种基本属性。例如,

x = 1:8
fft(x)
## [1] 36+0.000000i -4+9.656854i -4+4.000000i -4+1.656854i -4+0.000000i
## [6] -4-1.656854i -4-4.000000i -4-9.656854i

Mod(fft(x))
## [1] 36.000000 10.452504  5.656854  4.329569
## [5]  4.000000  4.329569  5.656854 10.452504

以下是相应的频率(可能有更简单的方法...)
freqs = seq(0,1/2,by=1/8)
freqs = c(freqs,-rev(freqs[-c(1,5)]))
## [1]  0.000  0.125  0.250  0.375  0.500
## [6] -0.375 -0.250 -0.125

对于实数输入,您只需要保留输出的前一半。有更有效的FFT算法适用于实数输入,但我不确定是否有任何R软件包实现它们。

对于复数输入,对称性不再成立:

set.seed(101); fft(x+rnorm(8)*1i)
# [1] 36.000000+ 1.756632i
# [2] -5.501913+ 8.349288i
# [3] -2.375197+ 4.040887i
# [4] -2.914446+ 1.690809i
# [5] -4.000000- 1.899475i
# [6] -5.085554- 1.622900i
# [7] -5.624803- 3.959113i
# [8] -2.498087-10.964420i

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