4. Convolution과 Filter를 ANSI C로 설계
>> x=[1 100 1 100 2 50 2 10 30 20 1 2];
>> h=[2 3 1 2 3];
>> conv(h,x)
ans =
2 203 303 305 508 508 359 380 198 294 118 117 137 64 7 6
>> filter(h,1,x)
ans =
2 203 303 305 508 508 359 380 198 294 118 117
일단 MATLAB으로 테스트한 테스트 데이터는 다음과 같다.
n |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
|
|
|
|
x |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
|
|
|
|
h |
1 |
1 |
1 |
|
|
|
|
|
|
|
|
|
|
|
|
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
|
|
|
|
|
|
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
|
|
|
|
|
|
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
|
|
|
|
|
|
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
|
y |
10 |
19 |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
.. |
6 |
3 |
1 |
|
|
<----- |
------ |
------ |
필 |
터 |
후 |
데 |
이 |
터 |
---> |
|
|
|
|
일단 카테고리 3번글에서 테스트한 데이터로 위의 convolution table을 만들어 보았다.
테이블에서 참고할 수 있듯이 convoultion데이터는 13개가 생기고( 0부터 Xn+ Yn-1 ),
필터후의 데이터는 10개가 생긴다.( 0부터 들어온 데이터의 갯수)
그래서 convoultion소스를 아래와 같이 구성해 보았다.
#include<stdio.h>
#include<stdlib.h>
void conv(int *h,int *x,int *y,int *filterY,int lengthH,int lengthX){
/*printf("%d %d %d",h,x,length);*/
int i=0,j=0;
int outLength= lengthX+(lengthH-1);
for(i=0; i< lengthX;i++)
for(j=0; j< lengthH;j++)
y[i+j]=x[i]*h[j]+y[i+j];
}
int main(){
//int x[]={10,9,8,7,6,5,4,3,2,1};
//int h[]={1,1,1,1};
int i=0;
int x[]={1,100,1,100,2,50,2,10,30,20,1,2};
int h[]={2,3,1,2,3};
int lengthH= sizeof(h) / sizeof(int);
int lengthX= sizeof(x) / sizeof(int);
int outLength= lengthX+(lengthH-1);
int *y;
int *filterY;
y=(int *)calloc( outLength,sizeof(int));
filterY=(int *)calloc( x, sizeof(int));
conv(h,x,y,filterY,lengthH,lengthX);
printf("x와 h의 convolution결과 :\n");
for(i=0;i<outLength; i++)
printf("%d ",y[i]);
}
그 결과
matlab에서 conv함수를 돌린 결과와 같았다.
이 후 filter함수의 구현은 단순하게 0~들어온 데이터의 index만큼만 새로운 배열에 복사하는 식으로 구현해서.
void filter(int *h,int *x,int *y,int *filterY,int lengthH,int lengthX){
int i=0;
conv(h,x,y,filterY,lengthH,lengthX);
for(i=0;i<lengthX;i++)
filterY[i]=y[i];
}
다음과같이 wraped 함수로 만들어 주었다.
그 결과
MATLAB에서 filter(h,x)로 돌린 결과와 같은 결과를 얻을 수 있었다.
구성한 소스에서는 int로 배열을 구성하였지만, double이나 float으로 구성한다면 매트랩같이 복잡한 값도 계산 할 수 있을 듯 하다.