글목록

2021년 5월 5일

Module 5. Savitzky-Golay smoothing - (4)Smoothing 함수 작성

다항식 Fitting 함수들이 모두 작성되었기 때문에 Smoothing 함수는 매우 간단하게 작성됩니다.

우선 배열을 변수로 입력할 수 있도록 아래와 같이 Type을 지정해둡니다. 이는 앞서 Sorting 함수를 작성할 때 사용했습니다.

함수의 반환값을 2개 이상의 배열로 반환하고 싶을 때, 이와 같이 배열을 하나의 변수 Type으로 지정해두면, 쉽게 구현할 수 있습니다.


'-----------------------------------
Public Type typeArray
  Y() As Variant
End Type
'-----------------------------------
Function PFit_SavitzkyGolay(iX(), iY(), iWidth As Long, Optional iOrder As Long = 3, Optional iDiffOrder As Long = -1) As typeArray()
  'Smoothing을 위한 x, y 데이터 배열과, 각 데이터포인트에서 smoothing을 수행하기 위한 데이터 폭, fitting 차수 및 미분차수를 입력합니다.
  Dim i As Long, j As Long, tX(), tY(), tA(), tFit() As typeArray, tCalcDiff As Boolean
  Dim tW As Long, n As Long

  'n차 다항식으로 fitting하기 위해서는 최소 n+1개 이상의 데이터가 필요합니다. 따라서, 데이터 폭이 입력된 차수에 비해 적다면, 데이터 폭을 늘려줍니다. 이때, 계산 위치의 앞과 뒤의 데이터 수를 동일하게 취하도록 하며, 데이터 폭은 2n+1개가 됩니다.
  If iWidth < iOrder + 1 Then tW = iOrder / 2 Else tW = iWidth / 2
  n = UBound(iX, 1)

  '만약, 입력된 미분차수가 음수이거나, fitting 차수보다 높다면, 미분계수를 계산하지 않습니다.
  '미분계수를 계산하는 경우라면, Smoothing 결과와 미분 계수를 반환하고, 미분계수를 계산하지 않는다면, Smoothing 결과만 반환합니다.
  tCalcDiff = (iDiffOrder > 0 And iDiffOrder < iOrder)
  If tCalcDiff Then
    ReDim tFit(1)
    ReDim tFit(0).Y(1 To n, 1 To 1)
    ReDim tFit(1).Y(1 To n, 1 To 1)
  Else
    ReDim tFit(0)
    ReDim tFit(0).Y(1 To n, 1 To 1)
  End If

  '각 점에 대하여, 데이터 폭만큼만 다항식 fitting하여 계수를 구하고, 구해진 계수를 이용하여 smoothing된 값 및 미분계수를 구하고, 구해진 결과를 1개 또는 2개의 배열로 반환해줍니다.
  For i = 1 + tW To n - tW
    tA = PolynomialFit(iX, iY, iOrder, i - tW, i + tW)
    tFit(0).Y(i, 1) = PFit_GetFitValueAt(iX(i, 1), tA)
    If tCalcDiff Then tFit(1).Y(i, 1) = PFit_GetDiffValueAt(iX(i, 1), tA, iDiffOrder)
  Next
  PFit_SavitzkyGolay = tFit
ErrorHandler:
  Erase tX, tY, tA, tFit
End Function 
'-----------------------------------

댓글 없음:

댓글 쓰기

의견이나 질문이 있으신 분은 언제든지 댓글을 달아주세요~

많이 본 글 :