python - 使用 scipy fft 计算信号的自相关给出了与直接计算不同的答案

标签 python numpy scipy fft

我正在尝试使用自相关是功率谱的傅里叶逆变换这一特性来计算信号的自相关。但是,当我使用 scipy(或 numpy)fft 来执行此操作并与自相关函数的直接计算进行比较时,我得到了错误的答案,具体来说,fft 版本在较大的延迟时间内以较小的负值趋于平稳,这是明显错了。

下面是我的 MWE,以及输出。我使用的 fft 错了吗?

import numpy as np
import matplotlib.pyplot as pl
from scipy.fftpack import fft, ifft


def autocorrelation(x) :
    xp = (x - np.average(x))/np.std(x)
    f = fft(xp)
    p = np.absolute(f)**2
    pi = ifft(p)
    return np.real(pi)[:len(xp)/2]/(len(xp))

def autocorrelation2(x):
    maxdelay = len(x)/5
    N = len(x)
    mean = np.average(x)
    var = np.var(x)
    xp = (x - mean)/np.sqrt(var)
    autocorrelation = np.zeros(maxdelay)
    for r in range(maxdelay):
        for k in range(N-r):
            autocorrelation[r] += xp[k]*xp[k+r]
        autocorrelation[r] /= float(N-r)
    return autocorrelation


def autocorrelation3(x):
    xp = (x - np.mean(x))/np.std(x)
    result = np.correlate(xp, xp, mode='full')
    return result[result.size/2:]/len(xp)

def main():
    t = np.linspace(0,20,1024)
    x = np.exp(-t**2)
    pl.plot(t[:200], autocorrelation(x)[:200],label='scipy fft')
    pl.plot(t[:200], autocorrelation2(x)[:200],label='direct autocorrelation')
    pl.plot(t[:200], autocorrelation3(x)[:200],label='numpy correlate')
    pl.legend()
    pl.show()


if __name__=='__main__':
    main()

enter image description here

最佳答案

离散 FT 假设信号是周期性的。因此,在基于 fft 的代码中,您正在计算环绕自相关。为避免这种情况,您必须执行某种形式的 0-padding:

def autocorrelation(x):
    xp = ifftshift((x - np.average(x))/np.std(x))
    n, = xp.shape
    xp = np.r_[xp[:n//2], np.zeros_like(xp), xp[n//2:]]
    f = fft(xp)
    p = np.absolute(f)**2
    pi = ifft(p)
    return np.real(pi)[:n//2]/(np.arange(n//2)[::-1]+n//2)

关于python - 使用 scipy fft 计算信号的自相关给出了与直接计算不同的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47850760/

相关文章:

python - ArgumentParser.add_argument : How to use action parameter with custom type parameter?

python - Matplotlib 不显示数字

python - 需要找到黑点

python - 模糊图像的特定部分

python - 从 session 中取消绑定(bind)对象

python - 使用 Splinter 从动态菜单中进行选择

python - shellcode是如何从C生成的? - 带有代码示例

python - 如何将数组传递给 Scipy Interpolate RectBivariateSpline?

python - 将带有 float 的 numpy 数组转换为二进制(0 或 1 个整数)

python - numpy/scipy 中的平方差和 (SSD)