크리에이티브 커먼즈 라이선스
Creative Commons License
지난 시간에는 AF (Averaging Filter) 에 대해 포스팅 했었지요 ㅋ

이번에는 앞에 Moving 이 들어갑니다 ㅋㅋ

Filter 개념을 접하게 되는 공대생들은 대부분 이것부터 맛보게 되실꺼에요 아마도 ㅋㅋ

한국말로는 이동 평균 필터!  ㅋㅋ

주식하시는 분들 '이평선, 이평선' 많이 하시죠? ㅋㅋ 이게 이동평균선의 줄임말입니다 ㅋ

그냥 평균 필터를 사용하는 경우에는 동적인 데이터 변화량을 도저히 반영할수가 없습니다.

시작부터 끝까지의 데이터를 평균내서 뿌려버리다 보니까 값의 변화폭 자체가 매우 작아져 버리다 못해

데이터 길이가 길어지면 길어질수록 변화가 없어져만 가겠지요 ㅋ

바꿔 생각해보면 infinit - point Moving Average Filter 가 되어버리는 것입니다 ㅋ

그럼 일단 늘상 하던대로 개념정리를 해야겠지요? ㅋㅋ


자 ㅋㅋㅋ

읽어보신 분들은 알겠지만 이번에는 재귀식을 사용하지 않겠습니다 ㅋㅋ

어차피 재귀식을 사용하는데 얻을수 있는 이점이 없거나 작을 경우에는 코드를 직관적으로 이해 할수 있도록 만들어 주는것이 훗날을 생각할때 훨씬 더 좋기 때문입니다 ㅋ

물론 MAF 의 차수가 엄청나게 높다면야 다시 생각해 봐야겠지만 구지 필터함수를 들고있을 필요는 없을것 같아요 ㅋㅋ

아래에 보여질 결과창은 Kalman Filter 의 이해라는 책에서 제공해주는 데이터를 이용하고,

제가 약간 수정 보완을 거친 자료입니다. ㅋ

데이터의 변화량을 잘 쫓아가면서도 잡음은 제거되어 나오는 형태의 그래프를 보실수 있을 거에요 ㅋ

물론! 파일은 올려드리겠습니다 ㅋㅋ

코드에서 눈여겨 보실점은 초기값을 0 가 아닌 처음들어오는 데이터로 함으로써 초기 오류를 줄였다는데 있어요 ㅋ

어려운 부분이 아니니까 스윽 보시면 이해되실꺼에요 ㅋㅋ

그리고 persistent 로 선언된 변수들이 있는데요 ㅋㅋ

http://iamaman.tistory.com/158

요기 가셔서 공부하세용 ㅋㅋ C 언어의 Static 선언과 비슷한거라고 생각하시면 됩니당 ㅋㅋ


씨퍼런 선이 필터 출력파형이네요 ㅋㅋ

잘 쫒아가고 있지요? ㅋㅋ

Matlab 에서는 MAF 함수를 따로 지원하지 않습니다 ㅋㅋ

이유는???

Filter 라는 함수에 b 변수배열을 1/n (n = point 수) 로 하고 a = 1 로하면??

형태는 fir 필터 형태지만 moving average filter 식과 같아지요??/

각각의 데이터에 1/n 을 곱해서 다시 다 더하니까요 ㅋㅋ

그래서 이걸 사용하라는 의미에서 제공을 안해주나봐요 ㅋㅋ


근데!!! 여기에 엄청난 맹점이 숨어있습니다 ~ ㅋㅋㅋㅋ

뭔지 아시는분이 계실려나???? 정말로 아신다면 대단하십니다!!!! 역시 세상은 엄청 넓군요 ㅋㅋ

그럼 밑에 손으로 짠 MAF 와 filter 내장함수를 이용해서 10point MAF 한 결과파형을 올려드릴테니까

한번 생각해 보세요 ~ ㅋㅋ

조그마케 해놓고 보면 잘 안나와서 한부분을 확대했어요 ㅋㅋ



짜잔~ ㅋㅋ

추세는 둘다 서로 잘 따라가는데 ㅋㅋ

같은 파형인것 같은데 이상하게 약간 차이가 나지요? ㅋㅋ

뉘미럴 왜그럴까! 개 썩을 ㅋㅋㅋ

아... filter 함수를 쓰면서 Phase Delay 인가???

물론 그럴수도 있지요 ㅋㅋ

그럼 Amplitude 는 왜 차이가 나는걸까요? 뉘미럴 개썩을 ㅋㅋㅋ

딜레마에 빠지게 됩니다 ㅋㅋ

그럼 일단 filtfilt 함수를 사용해서 delay 를 제거해보지용 ㅋㅋ

 


짜잔 ㅋㅋㅋ

자 ㅋㅋ

딜레이는 없습니다 ㅋㅋ 하지만 역시나 Amplitude 에서 차이를 보입니다 ㅋ

이게 무슨 개 거지같은 경우가 ㅋㅋㅋ

이유가 뭘까요?? ㅋㅋ

알아내셨나요??? ㅋㅋ

정답!~!!


손으로 짠 MAF 함수의 경우 : (data 합)/포인트수
filter 함수의 경우 : (각 데이터 / 포인트수) 를 전부 더한것 ㅋ

수식적으로는 100% 같습니다 ㅋㅋ

하지만 각각의 데이트를 다 나눠놓고 더하는것은 데이터를 나누는과정에서서 소수점 뒷자리가 계속 짤려나가게 되고 이걸 다시 더하다 보니 오차가 더 생기는 것이지요 ㅋㅋ

코딩을 짜는과정에서 이런 오류를 흔히 범할수 있습니다 ㅋㅋ

저처럼 이제 막 살짝 코딩 맛을 봐가는 사람은 머리쓴다고 저런 실수를 할수도 있지요 ㅋㅋ

다 더해놓고 나눌려면 큰 크기의 버퍼를 잡아야하고 그럼 스택의 낭비가 심하고, 잘못하면 OverFlow 날수도 있으니까 나는 식을 좀 바꺼나 하나하나 나눠놓고 더하겠다!!!

이런생각 말이에요 ㅋㅋㅋ

얼마나 위험한 생각인지 이제는 다들 아셨지요? ㅋㅋ


그리고 연산속도에서도 나누기 연산보다는 더하기 연산이 훨씬 시간이 적게 걸리니까 다 더하고 한번에 나누는것이 여러모로 좋아요 ㅋㅋ

이과정에서 버퍼 사이즈를 잘 결정하는 것은 프로그래머의 역량이겠지요 ㅋㅋ

물론 Matlab 에서는 크게 신경쓸것이 없지만

Embeded C 나 Window C 프로그래밍을 하는경우라면 이야기가 달라집니다 ㅋㅋ

Matlab 으로 짜실때는 뭐 크게 차이가 안나니까 그냥 filter 함수 이용하셔도 될듯 합니다 ㅋ

그럼 오늘도 즐거운 하루 되시공~ 

test 하는데 피룡한 파일들 올려드리도록 하겠습니다~~


수정합니다 ㅋㅋ

다시 해보니까 일단 제가 코드를 잘못짜놓고 헤맨부분이 있어요 뉘미럴 ㅋㅋ

위에서 한말이 다 거짓말은 아니구요 ㅋㅋ

두개의 방법사이에 약간의 오차가 있기는 한데 무시할수 있을 정도의 오차입니다 ㅋㅋ

10^-15 정도의 오차 ㅋㅋㅋ

일단 TestMovAvegFilter.m 파일에서

맨 마지막 줄을 output = filter(b,1,sonarAlt);

이렇게 고치시기 바랍니다 ㅋㅋㅋ

하마터면 잘못된 정보를 전할뻔 했군요 ㅋㅋㅋ

이런 잘못을 저지르는 분도 있을수 있으니 글은 모두 지우지 않고 줄을 그어놓겠습니당 ㅋㅋㅋ

좋은밤되세요 ㅋ
저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by J.Bear


티스토리 툴바