Convolution 연산을 이해하는 것은 신호를 분석함에 있어서 매우 중요한 역할을 한다. 일단 하나의 가정을 하고 가자. 우리는 LTI 시스템에서의 신호를 다루고자 한다. LTI(Linear Time-Invariant) 시스템은 선형성과 시불변성을 만족하는 시스템을 의미한다. 그 중 컨볼루션 연산을 이해하기 위해서는 시스템의 선형성에 주목할 필요가 있다.
선형성을 만족하는 시스템은 다음의 가산성(Additivity)와 동차성(Homogeneity)을 만족한다. 가산성이란 합쳐진 신호를 시스템에 넣었을 때 얻는 결과값과 분리된 신호를 각각 시스템에 넣어 얻은 결과 값을 합한 것이 같은 성질을 의미한다. 동차성은 이와 유사하게 입력 신호를 상수배하였을 때 출력된 결과 역시 상수배되는 성질을 의미한다. 가산성과 동차성을 수식으로 정리하면 다음과 같다.
신호에 대하여 우리는 시간에 따른 하나의 복잡한 신호로 볼수 있겠지만, 단 한 순간만 0이 아닌 값을 가지는 신호들의 합으로도 볼 수 있다. 이를 식으로 표현하면 다음과 같다.
이때 임펄스 함수는 한 지점을 제외한 나머지 영역에서 0을 값으로 가지는 함수를 의미한다. 만약 신호를 LTI 시스템에 넣게 된다면 어떻게 될 것인가? 해당 시스템에서는 가산성이 성립되기 때문에, 하나의 신호를 여러 종류의 합으로 보고, 각 신호를 시스템에 넣은 후 차후에 가산해도 큰 문제가 없을 것이다. 또한 동차성에 의해 입력값이 상수배가 되면 출력값도 그에 따라 상수배가 된다. 해당 신호는 n을 매개변수로 하는 신호이고, 시스템 역시 그러하다. 따라서 n을 포함하지 않은 나머지에 대해서는 상수 취급을 해줘도 무방하다는 것이다. 이 점들을 명심하면서 연속시간, 이산시간 영역에서 LTI 시스템을 거친 신호의 출력값을 다음과 같이 표현할 수 있다.
해당 식이 어떻게 나왔는 지에 대해서 풀자면, 각각 다음과 같다.
컨볼루션의 장점은 입력 신호의 종류와 상관없이 일관되게 임펄스 함수를 시스템에 넣어줌으로써 출력값을 쉽게 구할 수 있게 한다는 점이다. 하나의 신호를 여러 종류의 다른 신호의 합으로 보는 관점은 차후 푸리에 변환 같은 개념들을 다룰 때 큰 도움이 되므로 명심하자.
본론으로 돌아와 컴퓨터 상으로 컨볼루션 함수를 구현하기 위해서는 몇 가지 가정이 필요하다. 필요한 가정은 다음과 같다.
- 사용자가 정의한 부분을 제외하고 나머지는 0을 값으로 가진다. (컴퓨터는 무한을 계산하지 못하기 때문에 필요한 가정이다.)
- 모든 신호는 0부터 그 값을 시작한다. (컴퓨터가 배열을 표현하는 방식과 연관되어 있다.)
이 두 점을 고려하여, 컨볼루션 연산의 정의에 따라 다음과 같이 구현하였다.
//컨볼루션 함수
double* conv(double* x, double* h, ArrDestroyer& destroyer) {
int x_size = ArraySize(x);
int h_size = ArraySize(h);
int new_array_size = x_size + h_size - 1;
double* new_array = Zeros(new_array_size, destroyer);
for (int n = 0; n < new_array_size; n++) {
for (int k = 0; k < x_size; k++) {
if (n - k > -1 && n - k < h_size) new_array[n] += x[k] * h[n - k];
}
}
return new_array;
}
정의 자체를 그대로 코드로 옮긴 것이라 구현하는 데 있어서 큰 어려움은 없었다. 다만 한 가지 유의할 점이 있다면 조건문 정도인데, 해당 조건문이 필요한 이유는 어처피 0인 부분을 연산해 보았자 출력값에 영향을 주지 않기 때문에, 연산량을 줄이기 위해서 사용하였다. 이전 글에서 기본적으로 구현한 함수에 대해서 다루었는데 이를 참고하면 좋을 것 같아서 링크를 남긴다.
https://messy-developing-diary.tistory.com/36
Exercise 1 : DSP 실습 준비(여러 함수들 준비)
이론적인 공부만 하기 보다는, 프로그래밍을 통해서 구현해봄으로써 복습과 동시에 프로그래밍 공부도 같이 하는 것이 어떨까라는 생각에서 출발하였다. 지금 현재 짜고 있는 프로그램은 MATLAB
messy-developing-diary.tistory.com
이 것으로 이번 글을 마무리하고자 한다. (ps. 이번에 함수를 짜면서 배열을 다룰 일이 많았는데, 어설프게 연산량을 줄이겠다고 복잡하게 구현하는 것보다 정의에 충실해서 구현하는 것이 훨씬 깔끔할 수 있다는 팁 아닌 팁을 남긴다. )
'뭐라도 공부해보자!!( 이론 ) > Digital Signal Processing' 카테고리의 다른 글
FFT Algorithm, Cooley-Tukey Algorithm (0) | 2023.04.10 |
---|---|
푸리에 변환(Fourier Transform) (0) | 2023.01.06 |
Exercise 1 : DSP 실습 준비(여러 함수들 준비) (0) | 2022.12.20 |
1. Digital Signal Processing, 신호와 시스템 (0) | 2022.12.01 |
0. Digital Signal Processing, 개요 (0) | 2022.11.25 |