컨볼 루션에서 임펄스 응답 뒤집기


26

신호의 컨볼 루션 중에 프로세스 중에 임펄스 응답을 뒤집어 야하는 이유는 무엇입니까?


5
이 답변 의 후반부는 이해하는 데 도움 될 수 있습니다.
Dilip Sarwate

3
@DilipSarwate의 훌륭한 답변을 읽는 것 외에도 한 장의 종이를 가져 와서 시간 이동 및 스케일 버전의 임펄스 응답을 추가하여 LTI 시스템의 출력을 그래픽으로 계산하는 것이 좋습니다.
데브

1
인수를 뒤집을 수 있습니다. 결과는 동일합니다.
wakjah

답변:


29

이 질문이 커뮤니티 위키에 의해 주요 질문 중 하나로 반복적으로 발생하지 않기를 희망하면서 다른 의견에 대한 답변 (댓글에 언급 된 바와 같이)에 적응했습니다 ....

선형 (시간 불변) 시스템에 의한 임펄스 응답의 "충돌"은 없습니다. 선형시 불변 시스템의 출력은 "플립 된"임펄스 응답이 아니라 , 임펄스 응답의 스케일 및 시간 지연 버전의 합입니다 .

입력 신호 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] 위 배열의 행은 정확하게 크기가 조정되고 지연된 버전입니다. 응답까지 추가 임펄스 응답Y입력 신호에X. 하지만보다 구체적인 질문을하면
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

필터가 시변이 아닌 한 산란 방법을 사용하는 사람은 상상할 수 없습니다.이 경우 두 방법이 서로 다른 결과를 생성하고 하나가 더 적합 할 수 있습니다.


흥미 롭습니다! 그래서 내가보고 싶은 마지막 결론은 무엇입니까
Failed Scientist

당신의 건축 관심사는 흥미 롭습니다. 사용 가능한 캐시, SIMD 명령어 (SSE, AVX) 및 멀티 코어 아키텍처를 고려할 때 분산 된 방법이 병렬 계산에 더 적합한 것 같습니까? 그러나 나는 자세한 분석을 수행하지 않았습니다 ...
Fat32

@ Fat32 나도! 컨볼 루션 수집에서 축적이 곱셈에서 여러 코어를 사용하여 병목 현상이 발생할 수 있음을 의미합니까? 각 코어에 자체 누산기를 제공하고 마지막에 그들을 합산하면 완화 될 수 있습니다. 이 오버 헤드는 흩어져있는 회선의 추가 메모리 쓰기와 크게 비교되지 않을 것이라고 생각합니다.
Olli Niemitalo

실제로 는 수집 양식 병목 현상 보다 흩어져있는 양식의 효율성 에 더 관심이있었습니다. 현재 C 필터링 코드는 수집 양식에 있지만 아마도 ASM 코드와 관련하여 더 많은 SIMD SSE 확장으로 작성하는 경향이 있습니다. 흩어진 형태에 적합합니다. 그러나 내 tets 를 업데이트 해야합니다 :-))) 메모리 IO는 레지스터 누적과 비교할 때 분명히 문제입니다. 그리고 아마도 반복되는 메모리 IO의 페널티를 잃어
버렸을 것입니다

흩어지고 모이는 것보다 더 나은 단어를 아는 사람이 있습니까? 이것이 희소 컨볼 루션 커널을 위해 예약되어 있는지 확실하지 않습니다.
Olli Niemitalo

3

포인트 계산을 위해서만 '플립'됩니다.

@Dilip은 컨볼 루션 적분 / 합산이 나타내는 것을 설명하지만 h(t)계산을 위해 두 입력 기능 중 하나 (종종 )가 뒤집힌 이유를 설명하기 위해 입력 x[n]및 임펄스 응답을 갖는 이산 시간 시스템을 고려하십시오 h[n].

  • 당신은 할 수 귀하의 입력 기능을 x[n]하고, 각 비제 * 샘플 x[n]을 계산 샘플에서 임펄스 응답 조정 n시간 이동까지에 h[n](인과 관계를 가정 제로 다운 다이 h[n]). 이것은 (더 정확하게 '시간 역전'또는) 중 하나의 어떤 '반전'을 포함하지 않을 것이다 x[n]또는 h[n]. 그러나 결국에는 0이 아닌 각각에 대한 임펄스 응답의 모든 스케일 + 쉬프트 'echos'를 추가 / 중첩해야합니다 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 [nk]'를 의미하는 '시간-시프트 된 h [n]'을 제외한 모든 n은 동일합니다. 여기서 'k'는 임펄스 응답을 원하는 신호 x [n의 지점으로 이동시키는 데 사용되는 상수입니다. ]. 즉, x [2]에서 신호에 대한 응답을 계산하기위한 h [n-2].
abc

3

인덱스 c [n]에서 a [n]과 b [n]의 컨볼 루션은 다음과 같습니다.

"c [n]은 m + k = n 인 모든 곱 (a [k] b [m])의 합입니다."따라서 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 아, 으악! 때로는 질문이 무엇인지 이해하기가 어렵습니다. Izhak, 일단 당신이 찾고있는 대답을 이해하면, 당신은 내가 어디로 가고 있는지 이해할 것입니다. 지금은 무시하십시오!
learnvst

0

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

이제 핸드 파잉 형태는 여기에 포함 된 대칭을 명확하게 보여 주며 "플 리핑"이 포함되지 않습니다. 그러나이를 적절한 1 차원 적분으로 변환하려면 두 인수 중 하나를 실제 적분 변수로 만들어야합니다. 그것은 핸드 웨이브와 관련이없는 견고한 대칭 형태를 찾는 것입니다. 후자는 까다 롭습니다. 기본적으로 정규화를 다시 가져 와서 와 같은 무언가 (Dirac 델타 함수 / 분배 사용시)를 만들어야합니다.

t1,t2f(t1)g(t2)δ(tt1t2)dt1dt2
t1f(t1)dt1t2g(t2)δ(tt1t2)dt2
t1f(t1)dt1g(tt1)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.