翻转卷积中的脉冲响应


26

在对信号进行卷积时,为什么在此过程中需要翻转脉冲响应?


5
答案的后半部分可能会帮助您理解。
Dilip Sarwate 2012年

3
除了阅读@DilipSarwate的好答案之外,这是一个不错的练习,它可以通过加总时移和按比例缩放的脉冲响应形式来记录一张纸并以图形方式计算LTI系统的输出。
迪夫

1
请注意,您可以翻转任意一个参数-结果是相同的。
wakjah 2012年

Answers:


29

改编自对另一个问题的回答(如评论中所述),希望该问题不会被Community Wiki作为热门问题之一反复抛出。

线性(时间不变)系统没有冲动响应的“翻转”。线性时不变系统的输出是冲激响应的按比例缩放和延时形式的总和,而不是 “翻转”冲激响应。

我们将输入信号分解x总和缩放单元的脉冲信号的。该系统响应于该单位脉冲信号 , 0, 0, 1, 0, 0,脉冲响应脉冲响应

h[0], h[1],, h[n],
等由缩放属性单个输入值 x[0]或者,如果你喜欢
x[0](, 0, 0, 1, 0, 0,)= 0, 0, x[0], 0, 0,
创建响应
x[0]h[0],  x[0]h[1],,  x[0]h[n],

类似地,单个输入值或创建 X [ 1 ] 0 0 0 1 0 = 0 0 0 X [ 1 ] 0 创建响应 0 x [ 1 ] h [ 0 ] x [ 1x[1]

x[1](, 0, 0, 0, 1, 0,)= 0, 0, 0, x[1], 0,
注意对 x [ 1 ]的响应延迟。我们可以沿这个方向继续前进,但是最好切换到更表格的形式,并显示各个输出在时间上正确对齐。我们有 时间0 1 2 n n + 1 x [
0,x[1]h[0],  x[1]h[1],,  x[1]h[n1],x[1]h[n]
x[1]上述阵列中的行是精确的缩放和延迟版本与输入信号x的响应y相加的脉冲响应 但是,如果您问一个更具体的问题,例如
time012nn+1x[0]x[0]h[0]x[0]h[1]x[0]h[2]x[0]h[n]x[0]h[n+1]x[1]0x[1]h[0]x[1]h[1]x[1]h[n1]x[1]h[n]x[2]00x[2]h[0]x[2]h[n2]x[2]h[n1]x[m]000x[m]h[nm]x[m]h[nm+1]
yx

在时间输出是什么?n

那么您可以通过将第求和答案n

y[n]=x[0]h[n]+x[1]h[n1]+x[2]h[n2]++x[m]h[nm]+=m=0x[m]h[nm],
y[n]=x[n]h[0]+x[n1]h[1]+x[n2]h[2]++x[0]h[n]+=m=0x[nm]h[m],
n

4

这是一个C / C ++示例,该示例显示了可以进行卷积而无需反向使用脉冲响应。如果检查该convolve_scatter()函数,则任何地方都不会否定变量。这是散射卷积,其中使用冲激响应给定的权重将每个输入样本分散(求和)到内存中的多个输出样本。这是浪费的,因为将需要多次读取和写入输出样本。

通常,卷积是在聚集卷积中完成的,如中所示convolve_gather()。在这种方法中,每个输出样本是通过将输入样本收集(求和)而得到的,并以反向的脉冲响应作为权重来形成。完成后,输出样本驻留在用作累加器的处理器寄存器中。通常,这是选择的方法,因为每个过滤后的样本只有一个存储器写操作。现在,输入的内存读取次数更多,但散射方法中输出的内存读取次数却与之相同。

#include <stdio.h>

const int Nx = 5; 
const int x[Nx] = {1, 0, 0, 0, 2};
const int Ny = 3; 
const int y[Ny] = {1, 2, 3};
const int Nz = Nx+Ny-1;
int z[Nz];

void convolve_scatter() { // z = x conv y
  for (int k = 0; k < Nz; k++) {
    z[k] = 0;
  }
  for (int n = 0; n < Nx; n++) {
    for (int m = 0; m < Ny; m++) {
      z[n+m] += x[n]*y[m]; // No IR reversal
    }
  }
}

void convolve_gather() { // z = x conv y
  for (int k = 0; k < Nz; k++) {
    int accu = 0;
    for (int m = 0; m < Ny; m++) {
      int n = k+m - Ny + 1;
      if (n >= 0 && n < Nx) {
        accu += x[n]*y[Ny-m-1]; // IR reversed here
      }
    }
    z[k] = accu;
  }
}

void print() {
  for (int k = 0; k < Nz; k++) {
    printf("%d ", z[k]);
  }
  printf("\n");
}

int main() {
  convolve_scatter();
  print();
  convolve_gather();
  print();
}

它对序列进行卷积:

1 0 0 0 2
1 2 3

并使用两种卷积方法输出:

1 2 3 0 2 4 6

我无法想象有人使用散射方法,除非滤波器是随时间变化的,在这种情况下,两种方法将产生不同的结果,并且一种方法可能更合适。


有趣!那么我有兴趣看到的最后结论是什么
失败的科学家,

您对架构的关注很有趣。考虑到可用的缓存,SIMD指令(SSE,AVX)和多核体系结构,分散的方法似乎更适合并行计算?但是我还没有进行详细的分析……
Fat32

@ Fat32我也不行!您是说,积累卷积的积累可能会成为多个乘法工作的瓶颈?通过为每个内核分配自己的累加器并在末尾求和,可以缓解这种情况。我认为与分散卷积中的额外内存写入相比,此开销不会太大。
Olli Niemitalo

其实我更关心的是分散形式的效率比聚会形式bottleneck.My当前的C过滤代码是(最有可能)在聚会的形式,但是当它涉及到ASM代码我倾向于把它们写在SIMD SSE扩展指令这是更适用于分散形式。我必须更新自己的tets,但是:-)))与寄存器累积相比,内存IO绝对是一个问题。可能我错过了重复存储IO的惩罚...
Fat32

有谁能比散布和聚集更好的话?我不确定这些是否保留用于稀疏卷积内核。
Olli Niemitalo

3

它只是“翻转”用于逐点计算。

@Dilip解释了卷积积分/求和表示的含义,但要解释为什么两个输入函数之一(通常h(t))出于计算目的而被翻转,请考虑具有输入x[n]和脉冲响应的离散时间系统h[n]

  • 您可以使用输入函数x[n],并为每个非零*样本x[n]计算从样本开始的缩放脉冲响应,n直到时间平移到h[n]零为止(假定为因果关系h[n])。这将涉及没有“翻转”(或更准确地“时间反转”)的任一x[n]h[n]。但是,最后,您将不得不为每个非零的脉冲响应添加/叠加所有这些比例缩放和移位的“回声” x[n]

  • x[0]k

    k=x[k]h[nk]
    h[n]x[n],是x[0]h[0]。然后,增加k1将h[n]移至正确的一个时间步长,以使时间倒数h[n]的第二个条目(h[1])现在位于的顶部x[0],等待相乘。就像在以前的方法中所做的那样,这将x[0]h[1]在时间上产生期望的贡献n=1

x[n]

x[n]=0
h[n]y[n]

n

@Dilip。除“时移h [n]”(表示“ h [nk]”外)外,所有n均相同,其中“ k”是用于将脉冲响应移至信号x [n的所需点]的常数]。即:h [n-2]用于计算对x [2]处信号的响应。
2013年

3

在索引c [n]处,a [n]和b [n​​]的卷积为:

“ c [n]是所有乘积(a [k] b [m])的总和,使得m + k = n,”因此m = n-k或k = n-m,这意味着序列之一必须翻转。

现在,为什么卷积首先表现为这种方式?因为它与乘法多项式有关。

将两个多项式相乘会得出一个具有系数的新多项式。乘积多项式的系数定义了卷积运算。现在,在信号处理中,这些多项式是传递函数-拉普拉斯变换或z变换,每个系数对应于不同的时间延迟。乘积和被乘数的系数匹配会导致以下事实:“一个表示形式的乘法对应于变换表示形式中的卷积”。

在此处输入图片说明


0

在卷积期间,根本不需要发生脉冲响应的“翻转”。

但是,如果要防止任何相位改变,则可以用脉冲响应对信号进行卷积,然后反转脉冲响应并重新进行卷积以消除相位影响。

在离线处理中,您可以像在第一次卷积后一样轻松地反转信号以获得相同的结论(如注释所示)。


3
y(t)=x(τ)h(tτ)dτh(t)x(t)h(t)=h(t)x(t)

@JasonR啊,哎呀!有时很难看到问题的根源。伊扎克,一旦您了解了所需的答案,您就会了解我的去向。现在忽略我!
learnvst

0

f(τ)g(tτ)dτ
t1+t2=tf(t1)g(t2)dt1dt2
fgt

t1,t2f(t1)g(t2)δ(tt1t2)dt1dt2
t1f(t1)dt1t2g(t2)δ(tt1t2)dt2
t1f(t1)dt1g(tt1)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.