代码之家  ›  专栏  ›  技术社区  ›  Brad Solomon

scipy。信号卷积给出的结果与卷积积分的手动计算不同

  •  2
  • Brad Solomon  · 技术社区  · 7 年前

    假设我有两个功能,

    f(t)=sin(t)

    g(t)=成本(t)

    我知道 f g

    0.5*t*sin(t)

    (手工解决 here ),并通过以下方式:

    import sympy as sp
    
    t, tau = sp.symbols('t tau')
    sol = sp.integrate(sp.sin(t - tau) * sp.cos(tau), (tau, 0, t))
    print(sol)
    # t*sin(t)/2
    

    convolve ? 目前,我得到了两个非常不同的输出:

    import numpy as np
    from scipy import signal
    
    t = np.linspace(-10, 10, 1000)
    f = np.sin(t)
    g = np.cos(t)
    conv = 0.5 * t * np.sin(t)
    
    print(conv)
    # [-2.72  -2.63  -2.54  -2.449 -2.357 -2.264 -2.171 -2.078 -1.984 -1.89  ...,
    #  -1.89  -1.984 -2.078 -2.171 -2.264 -2.357 -2.449 -2.54  -2.63  -2.72 ]
    
    print(signal.convolve(f, g, mode='same'))
    # [ 138.098  134.167  130.164  126.092  121.953  117.747  113.476  109.142
    #   104.746  100.29  ...,  -95.775 -100.29  -104.746 -109.142 -113.476
    #  -117.747 -121.953 -126.092 -130.164 -134.167]
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   user6655984 user6655984    7 年前

    首先 signal.convolve 方法执行求和。为了使其近似积分,需要乘以步长dt。

    其次,产生0.5*t*sin(t)的积分只涉及从0开始的值:将f(tau)*g(t-tau)与tau从0到t进行积分。为了用离散卷积模拟这一点,从0开始邻域空间,并选择mode='full',然后从开始将结果截断为大小。这样,卷积的第一个元素将涉及很少的项,因此它们基本上从0开始。

    n = 1000
    t = np.linspace(0, 10, n)
    dt = t[1] - t[0]
    f = np.sin(t)
    g = np.cos(t)
    conv = 0.5 * t * np.sin(t)
    conv2 = signal.convolve(f, g, mode='full')[:n] * dt
    plt.plot(t, conv)   # assuming import matplotlib.pyplot as plt
    plt.show()
    plt.plot(t, conv2)
    plt.show()
    

    compare

    得到消极的部分,同样的事情,但是 t = -np.linspace(0, 10, n) . 注意,t现在应该向后走,仍然从0开始-就像积分一样。