[컴퓨터 과학]컴퓨터로 여러 함수들을 계산하는 방법
개발을 하다보니, sin 함수같은 삼각함수들을 어떻게 계산하는지 궁금해졌다. 사람의 경우엔 사칙연산만을 이용하여 값을 구하는 경우가 일반적이다. 하지만 컴퓨터의 경우엔 근삿값이기는 하지만 $\sqrt x$같은 값들도 순식간에 구해버린다.
검색을 해보니 테일러 급수라는 것을 발견하였는데, 이를 이용하여 구하는 모양이다. 식은 다음과 같다.
$$T_f(x)=\sum_{n=0}^{\infty }\frac{f^{(n)}(a)}{n!}(x-a)^n$$
위 함수는 특정 구간 $(a,\ b)$에서 함수 $f(x)$와 같게 된다. 즉, $x\in (a,\ b)$일 때, $T_f(x)=f(x)$이다. 이를 수렴 구간이라 한다.
(단, 함수 $f(x)$는 매끄러운 함수여야 한다. 즉, 무한 번 미분 가능해야 한다. 예를 들어 $f(x)=x$와 같은 함수나 $f(x)=e^x$와 같은 함수들은 무한 번 미분 가능하다.)
테일러 급수가 함수 $f(x)$와 같다는 것의 증명은 이 글에서 다루지 않겠다. 귀찮기도 하고 필자는 수학자가 아닐 뿐더러 수학을 목적으로 하지도 않는다. 수학을 수단으로써 바라보는 공학자에 가깝다. 아무튼 이를 이용하여 sin 함수를 계산하여 보자.
sin 함수의 테일러 급수는 다음과 같다.
$$\sin (x)=\sum_{n=0}^{\infty }\frac{(-1)^n}{(2n+1)!}x^{2n+1}$$
놀랍게도 위 테일러 급수의 수렴 구간은 실수 전체이기 때문에 항상 같다. 이를 C++로 구현하면 다음과 같다.
#include <iostream>
using namespace std;
double pow(double x, int n) {
for (int i = 1; i < n; i++)
x *= x;
return x;
}
double fac(int n) {
double result = 1;
for (int i = 2; i <= n; i++)
result *= i;
return result;
}
double sin(double x) {
double sum = 0;
for (int i = 0; i < 100; i++) // 무한급수를 계산할 수는 없기에 100번만 반복한다.
sum += pow(-1, i) / fac(2 * i + 1) * pow(x, 2 * i + 1);
return sum;
}
int main(void) {
cout << sin(1) << endl;
return 0;
}
출력: 0.841471
$\approx \sin (1)$로 실제 값과 어느정도 비슷하게 나온다.