gpt4 book ai didi

javascript - 使用 numpy.irfft 将算法转换为 JavaScript

转载 作者:行者123 更新时间:2023-11-30 17:55:51 26 4
gpt4 key购买 nike

我正在尝试将最初使用 numpy 编写的算法转换为 JavaScript,但我无法通过反向 FFT 重现结果。

原始算法使用numpy.fft.rfftnumpy.fft.irfft:

# Get the amplitude
amplitudes = abs(np.fft.rfft(buf, axis=0))

# Randomize phases
ph = np.random.uniform(0, 2*np.pi, (amplitudes.shape[0], 1)) * 1j
amplitudes = amplitudes * np.exp(ph)

# do the inverse FFT
buf = np.fft.irfft(amplitudes, axis=0)

我找到了 a JavaScript library这似乎可以完成 FFT 的工作,我正在使用 mathjs用于矩阵/向量工作。

我做了很多尝试,问题是我不知道我应该做什么来模仿numpy.fft.irfft

2 个 FFT 之间的差异:

  • JavaScript FFT 函数返回一个具有负频率的复数输出,因此它包含的点数是使用 numpy.fft.rfft 获得的结果的 2 倍。尽管正频率的振幅 [0, WIN/2] 似乎匹配。

  • JavaScript iFFT 返回复数输出,而 numpy.fft.rfft 返回实数输出。

回答

感谢@hotpaw2 我设法解决了我的问题。

实信号的频谱是对称的,numpy.fft.rfft 仅返回该频谱的唯一分量。因此,对于 128 个样本 block ,numpy.fft.rfft 返回包含 128/2 + 1 值的频谱,即 65 值。

因此,如果我想做同样的事情,我需要从振幅中丢弃所有对称值,然后应用相变。

对于反向 FFT:“要从全长 IFFT 获得纯实数输出,输入必须是复共轭对称的”。因此,我需要通过使实部对称,虚部镜像对称来重建光谱。

这是算法:

fft(1, re, im)

amplitudes = math.select(re)
.subset([math.range(0, frameCount / 2)]) // get only the unique part
.abs().done() // input signal is real, so abs value of `re` is the amplitude

// Apply the new phases
re = math.emultiply(math.cos(phases), amplitudes)
im = math.emultiply(math.sin(phases), amplitudes)

// Rebuild `re` and `im` by adding the symetric part
re = math.concat(re, math.subset(re, [symRange]).reverse())
im = math.concat(im, math.select(im).subset([symRange]).emultiply(-1).done().reverse())

// do the inverse FFT
fft(-1, re, im)

最佳答案

要从全长 IFFT 获得纯实数输出,输入必须是复共轭对称的(对于频率输入的上半部分或另一半频率输入,实部相同,虚部镜像对称取反)。

对于复数共轭输入,正向或反向 FFT 计算结果的虚部应该只会以接近零的微小数值噪声值结束(由于有限精度四舍五入)。

关于javascript - 使用 numpy.irfft 将算法转换为 JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18061711/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com