오늘은 XY 데이터 포인트들로 이루어진 곡선상에서 극대점 및 극소점을 찾는데 있어서 편리하게 사용할 수 있는 루틴을 하나 소개하고자 합니다. 다만 IDL에 기본적으로 내장된 것이 아니라서 따로 받아서 사용해야 하는데요. 소스코드 파일을 이 게시물에 첨부해놓았습니다. 루틴의 이름은 LOCAL_MAX_FINDER입니다. 이 내용은 IDL 본사인 Harris의 IDL Datapoint 블로그에 최근에 올라온 내용을 참조하였음을 밝혀둡니다.
이 루틴의 사용법은 간단합니다. 대상이 되는 XY 데이터를 다음 예문과 같은 방식으로 입력 인자로 넣어주면 됩니다. 그러면 극대점에 해당되는 위치에 해당되는 인덱스들을 전달해주게 됩니다. 그리고 /MINIMA 키워드를 사용할 경우에는 극소점을 찾게 됩니다. 따라서 극대점 및 극소점들을 모두 찾으려면 이 루틴을 두번 사용해주면 됩니다.
ind = LOCAL_MAX_FINDER(xdata, ydata)
ind = LOCAL_MAX_FINDER(xdata, ydata, /MINIMA)
다음과 같은 XY 예제 데이터를 가상으로 만들고 여기에 이 루틴을 사용하여 극대/극소 점들을 찾아봅시다. 먼저 가상 데이터의 생성 및 그 형태를 그림으로 그리는 과정만 먼저 거치게 되면 다음과 같은 그림을 얻게 됩니다. 이 곡선상에서 극대 및 극소 포인트들을 찾아보려고 합니다.
xvals = FINDGEN(2000)
yvals = 2*SIN(xvals*(2*!PI/500)) + SIN(xvals*(2*!PI/1000))
win = WINDOW(DIMENSIONS=[600, 500])
p = PLOT(xvals, yvals, /CURRENT, $
XTITLE='X Position', YTITLE='Amplitude', $
YMINOR=3, XMINOR=3, TITLE='Neat Local Max/Min Example')
먼저 극대점들부터 찾기 위하여 다음과 같이 LOCAL_MAX_FINDER 루틴을 사용합니다. 처리 결과는 극대점에 해당되는 데이터 포인트들의 인덱스들로 구성된 배열이 되는데, lmax_ind라는 이름으로 전달받았습니다. 뒤이어 SCATTERPLOT 함수를 사용하여이 극대점들만 선별적으로 표시하는 과정까지 다음과 같이 거치게 되면, 다음과 같은 그림을 얻게 됩니다.
lmax_ind = LOCAL_MAX_FINDER(xvals, yvals)
x_lmax = xvals[lmax_ind]
y_lmax = yvals[lmax_ind]
p_lmax = SCATTERPLOT(x_lmax, y_lmax, /OVERPLOT, $
SYMBOL='square', SYM_COLOR='red', /SYM_FILLED)
위 그림에서 볼 수 있듯이, 극대점들이 식별이 되어 빨간 점들로 표시되어 있음을 알 수 있습니다. 극소점들의 경우는 위와 거의 유사한 과정을 거칩니다. 다만 앞서 언급했듯이 LOCAL_MAX_FINDER 루틴을 사용할 때 /MINIMA 키워드를 함께 사용해주면 된다는차이점만 존재합니다. 어쨌든 이러한 과정은 다음과 같으며, 이렇게 처리하면 다음과 같은 그림을 얻게 됩니다.
lmin_ind = LOCAL_MAX_FINDER(xvals, yvals, /MINIMA)
x_lmin = xvals[lmin_ind]
y_lmin = yvals[lmin_ind]
p_lmin = SCATTERPLOT(x_lmin, y_lmin, /OVERPLOT, $
SYMBOL='square', SYM_COLOR='blue', /SYM_FILLED)
위 그림에서 볼 수 있듯이, 극소점들이 식별이 되어 파란 점들로 표시되어 있음을 알 수 있습니다. 이와 같은 방식으로 사용하면 됩니다. 다만 값의 급격한 변동이 자주 발생하는, 즉 노이즈가 심한 데이터의 경우에는 LOCAL_MAX_FINDER를 바로 적용할 경우 너무나 많은 극대점 또는 극소점들이 나타날 수 밖에 없습니다. 따라서 이러한 경우에는 데이터의 변동 패턴에 대한 fitting 처리를 거쳐서 부드러운 패턴으로 변형한 후에 이 LOCAL_MAX_FINDER를 적용하는 것이 더 효율적일 것으로 생각합니다.
LOCAL_MAX_FINDER의 소스코드 파일을 아래에 첨부합니다. 참고로, 이 코드의 내용은 원래 출처에서는 LIST, ToArray와 같은 IDL 8.x 버전에서만 유효한 내용들이 있어서, 제가 약간 수정을 해서 어느 버전의 IDL에서든 사용 가능하도록 해놓았음을 밝혀둡니다.
'IDL > Math' 카테고리의 다른 글
| MPFITELLIPSE 함수를 이용한 타원형 궤적 근사 (0) | 2016.04.25 |
|---|---|
| 세 점을 잇는 원의 궤적을 구하고 그려보기 (0) | 2016.04.22 |
| Power Spectrum을 이용한 태양 흑점 주기 계산 (0) | 2016.01.13 |
| Power Spectrum in IDL (0) | 2016.01.04 |
| LU Decomposition in IDL (0) | 2015.10.07 |