이 글에서는 라그랑주(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²)으로, 데이터 점의 개수가 많아질수록 계산량이 늘어난다는 점을 고려하면 좋습니다. 실험 데이터의 역산이나 수치 해석에서 특정 출력값에 대응하는 입력값을 찾아야 할 때 유용하게 활용할 수 있습니다.