Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 구현하는 베셀(Bessel) 보간 공식: 개념부터 예제 코드까지

보간(Interpolation)은 이미 알고 있는 값들 사이에 존재하는 미지의 값을 추정하는 기법입니다. 즉, 이산적으로 주어진 데이터 포인트 집합의 범위 안에서 새로운 데이터 포인트를 만들어내는 과정을 말합니다.

보간을 사용하는 대표적인 이유는 계산 비용을 줄일 수 있기 때문입니다. 특정 값을 계산하는 수식(함수)이 너무 복잡하거나 연산 비용이 크게 들 때, 우리는 보간을 활용하는 것을 선호합니다. 원래의 함수를 사용해 몇 개의 데이터 포인트만 직접 계산하고, 나머지 값들은 보간을 통해 추정하는 방식입니다. 물론 완벽하게 정확하지는 않지만, 실제 값에 상당히 가까운 결과를 얻을 수 있습니다.

결국 이 방법에서는 보간 오차로 인한 손실보다 절약되는 계산 비용과 단순성이 더 큰 가치를 지닌다고 판단하는 것입니다.

베셀의 보간 공식 (Bessel's Interpolation Formula)

f(u) = {(f(0)+f(1))/2} + {u − ½}𝛥f(0) + {u(u−1)/2!}{(𝛥2f(−1) + 𝛥2f(0))/2} + {u(u−1)(u−½)/3!}𝛥3f(−1) + {u(u+1)(u−1)(u−2)/4!}{(𝛥4f(−2) + 𝛥4f(−1))/2} + …

여기서 각 기호의 의미는 다음과 같습니다.

  • f(0): 원점(origin point)으로, 일반적으로 데이터의 중간 지점을 의미합니다.
  • u = x − f(0) / h: h는 차분 간격(interval of difference)입니다.

C++ 예제 코드

아래는 베셀 보간을 구현한 C++ 프로그램입니다.

#include <iostream>
using namespace std;
float calU(float u, int n){
    if (n == 0)
        return 1;
    float result = u;
    for (int i = 1; i <= n / 2; i++)
        result = result*(u - i);
    for (int i = 1; i < n / 2; i++)
        result = result*(u + i);
    return result;
}
int factorial(int n){
    if(n == 1)
        return 1;
    return n * factorial(n-1);
}
int main(){
    int n = 6;
    float x[] = { 50, 51, 52, 53, 54, 55 };
    float y[n][n];
    y[0][0] = 8.000;
    y[1][0] = 7.746;
    y[2][0] = 7.674;
    y[3][0] = 7.571;
    y[4][0] = 7.469;
    y[5][0] = 7.231;
    for (int i = 1; i < n; i++)
        for (int j = 0; j < n - i; j++)
            y[j][i] = y[j + 1][i - 1] - y[j][i - 1];
    float value = 53.2;
    float sum = (y[2][0] + y[3][0]) / 2;
    int index;
    if (n % 2)
        index = n/2;
    else
        index = n/2 - 1;
    float u = (value - x[index]) / (x[1] - x[0]);
    for (int i = 1; i < n; i++) {
        if (i % 2)
            sum+= (((u-(0.5))*calU(u, i - 1)*y[index][i])/factorial(i));
        else
            sum+= ((calU(u, i)*(y[index][i]+y[-- index][i])/(factorial(i)*2)));
    }
    cout<<"Value at "<<value<<" found using Bessels's interpolation is "<<sum;
    return 0;
}

코드 동작 방식

  • calU(): 베셀 공식에 필요한 u의 다항식 항을 계산하는 함수입니다.
  • factorial(): 재귀 호출을 통해 팩토리얼 값을 구합니다.
  • 차분 테이블 생성: 주어진 y값들로 전진 차분(forward difference) 테이블을 만듭니다.
  • 중심점 선택: 데이터 개수가 짝수일 경우 중앙 바로 앞 인덱스를 기준점으로 삼습니다.
  • u 계산: 구하고자 하는 x값(53.2)을 기준점과 간격을 이용해 정규화합니다.
  • 항별 합산: 홀수 차 항과 짝수 차 항을 구분하여 공식에 따라 누적 합산합니다.

실행 결과

Value at 53.2 found using Bessels's interpolation is 7.54985

x = 53.2 지점의 함수값을 베셀 보간으로 추정한 결과 7.54985가 출력됩니다. 이처럼 베셀 보간은 중심 차분을 활용하기 때문에 데이터 중앙 부근에서 특히 높은 정확도를 보여주며, 수치해석에서 널리 사용되는 보간 기법 중 하나입니다.