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

C++로 배우는 라그랑주(Lagrange) 공식 기반 역보간(Inverse Interpolation) 구현


이 글에서는 라그랑주(Lagrange) 공식을 활용하여 역보간(Inverse Interpolation)을 구현하는 C++ 프로그램을 소개합니다.

일반적인 보간법이 표로 주어진 독립변수 x의 값에 대응하는 종속변수 y의 값을 찾는 것이라면, 역보간은 그 반대의 작업입니다. 즉, 알려지지 않은 함수 f(x)가 두 개 이상의 표 값 사이에 존재할 때, 종속변수 y의 특정 값으로부터 그에 대응하는 독립변수 x의 값을 역으로 추정하는 방법을 의미합니다.

역보간의 동작 원리

라그랑주 보간 공식은 기본적으로 여러 개의 좌표점 (x₁, y₁), (x₂, y₂), …, (xₙ, yₙ)이 있을 때, x값을 넣어 y값을 계산하는 데 사용됩니다. 역보간에서는 이 공식에서 x와 y의 역할을 서로 맞바꾸어, 목표 y값에 가장 가까운 x값을 아래와 같은 형태로 근사합니다.

x(y) ≈ Σ [ xᵢ × Π (y − yⱼ) / (yᵢ − yⱼ) ]  (단, j ≠ i)

각 데이터 점마다 해당 점의 x값에 나머지 점들로 만든 라그랑주 기저항(가중치)을 곱한 뒤 모두 더하면, 목표 y값에 대응하는 x의 근삿값을 얻을 수 있습니다. 이때 역보간은 함수가 단조증가 또는 단조감소(일대일 대응)일 때 가장 정확하게 작동한다는 점을 유의해야 합니다.

C++ 구현 코드

#include <bits/stdc++.h>
using namespace std;

// x와 y 값을 묶어 저장하기 위한 구조체
struct Data {
    double x, y;
};

// 라그랑주 공식으로 역보간을 계산하는 함수
double calc_invinter(Data d[], int n, double y) {
    double x = 0;
    for (int i = 0; i < n; i++) {
        double xi = d[i].x;
        for (int j = 0; j < n; j++) {
            if (j != i) {
                // 라그랑주 기저항: (y - y_j) / (y_i - y_j)
                xi = xi * (y - d[j].y) / (d[i].y - d[j].y);
            }
        }
        x += xi; // 각 점의 기여분을 누적
    }
    return x;
}

int main() {
    Data d[] = {
        { 1.27, 2.3 },
        { 2.25, 2.95 },
        { 2.5, 3.5 },
        { 3.6, 5.1 }
    };
    int n = sizeof(d) / sizeof(d[0]); // 데이터 개수를 자동으로 계산
    double y = 4.5;

    cout << "Value of x (y = 4.5) : " << calc_invinter(d, n, y) << endl;
    return 0;
}

실행 결과

Value of x (y = 4.5) : 2.79498

코드 설명

  • Data 구조체: 한 좌표점의 x값과 y값을 하나의 단위로 묶어 관리합니다.
  • calc_invinter 함수: 바깥 반복문(i)은 기준이 되는 데이터 점을 선택하고, 안쪽 반복문(j)은 나머지 점들을 이용해 라그랑주 기저항을 차례로 곱합니다. 모든 점의 기여분을 더하면 최종 x값이 됩니다.
  • 데이터 개수(n): 반드시 실제 배열의 크기와 일치해야 합니다. 배열 크기를 초과하도록 n을 설정하면 범위를 벗어난 메모리를 참조하게 되어 잘못된 결과나 오류가 발생할 수 있습니다. 위 예제에서는 sizeof 연산자로 데이터 개수를 자동 계산하도록 개선했습니다.

마무리

이처럼 라그랑주 공식의 변수 역할만 바꾸면 별도의 복잡한 변환 없이도 역보간을 손쉽게 구현할 수 있습니다. 이 알고리즘의 시간 복잡도는 O(n²)으로, 데이터 점의 개수가 많아질수록 계산량이 늘어난다는 점을 고려하면 좋습니다. 실험 데이터의 역산이나 수치 해석에서 특정 출력값에 대응하는 입력값을 찾아야 할 때 유용하게 활용할 수 있습니다.