Devlog

[수치해석] 테일러 급수 (2) - 테일러 다항식과 테일러 다항식의 오차 구하기 본문

수학 관련/수치해석

[수치해석] 테일러 급수 (2) - 테일러 다항식과 테일러 다항식의 오차 구하기

recoma 2022. 7. 14. 00:25

테일러 급수 공식 (출처: 위키백과)

테일러 급수 시리즈
1. 테일러 급수 전개하기
2. 테일러 다항식과 테일러 다항식의 오차 계산하기
해당 예제들은 MATLAB으로 배우는 공학 수치해석 (한빛 아카데미) 에서 참고했습니다.
일부 공식은 표준 공식에서 저의 주관적인 해석으로 약간 변형한 부분이 있습니다. 가능한 영향이 미치지 않는 범위에서 변형하려고 노력했으나 틀린 부분이 있으면 지적 부탁드립니다.

지난 챕터에서는 테일러 급수의 정의와 증명, 그리고 sin/cos, 제곱근 같은 예제를 설명했습니다. 테일러 급수는 전체 구간이 무한대로 미분이 가능한 함수들을 상대로 합으로 전개해서 값을 구하는 끝내주는 공식이지만, 어디까지나 정확한 값이 아닌 근사값만을 구할 뿐입니다. 그렇기 때문에 실제 함수의 값과 테일러 급수를 통한 근사값의 사이에는 항상 빈틈이 있습니다. 이번 챕터에서는 테일러 급수의 오차를 구하기 위한 테일러 다항식의 개념과 테일러 다항식의 오차 범위를 구하는 방법에 대해서 설명합니다.

테일러 다항식

테일러 다항식과 테일러 급수의 차이는 미분의 횟수 입니다. 테일러 급수는 무한대로 미분해서 값을 구하지만 테일러 다항식은 그 미분의 횟수가 정해져 있습니다.

예를 들어, 지난 챕터에서 제곱근 함수를 직접 구현했을 때, 루트2를 계산하기 위해 총 135번의 미분을 진행했었습니다. 이를 135차 테일러 다항식이라고 합니다. 일반화를 하면 n번 미분한 식을 n차 테일러 다항식이라고 합니다. 보통 n차 테일러 다항식을 pn(x)으로 표현합니다.

테일러 다항식 오차 구하기

공식

테일러 다항식의 오차 공식은 아래와 같습니다.

실제값 f(x)에서 테일러 다항식에 대한 값 p(x)를 뺀 값이 오차가 됩니다. 겉으로 보기에는 오차라고 해봐야 우항에 있는 것만 바로 계산하면 끝나는 것처럼 보이지만 Cx가 걸립니다. 이 Cx는 a와 x 사이의 값이 됩니다.

사실 이 상태에서 정확한 오차를 구할 순 없지만 a ~ x 사이에서 f(n+1)(Cx)의 최대값을 구함으로써 오차의 경계 정도는 계산할 수 있습니다.

예제1: e^x (부제: 테일러 다항식으로 구한 자연상수 e의 오차범위 구하기)

테일러 급수로 구한 자연상수 e에 대한 오차범위를 구하려고 합니다. 따라서 e^x를 예로 들어봅시다. e^x에 대한 테일러 다항식은 아래와 같습니다. 이때 a는 0이 됩니다.

테일러 다항식 오차 공식에 따라 오차를 계산해 보면

위와 같은 식이 됩니다. 자연상수 e는 아무리 미분을 해도 그대로이기 때문에 e^{Cx}를 그대로 작성하면 됩니다.

우리가 원하는 건 e^1이므로 x에 1을 대입합니다.

Cx의 범위는 0이상 1이하가 되므로

이걸 오차에 적용해 보면

이렇게 해서 테일러 다항식으로 구해진 자연상수에 대한 오차의 범위는 위와 같게 됩니다. 몇번 미분했냐에 따라 오차 범위는 더 좁아지며 예를 들어 3차 테일러 다항식에 대한 오차 범위는

위와 같게 됩니다.

자연상수 오차를 구하는 식을 마음같아선 직접 코딩하고 싶지만 오차 범위에서 자연상수가 붙어있기 때문에 아마 정밀한 구현을 하기가 쉽지는 않을 것 같습니다.

예제2: 제곱근

제곱근에 대한 테일러 급수는 다음과 같습니다.

테일러 다항식으로 표현하면 아래와 같습니다. 합을 사용한 공식 자체가 복잡하기 때문에 n차 다항식이 아닌 2차 테일러 다항식에 대한 오차를 구해봅시다. (풀이를 위해 2차까지만 전개하고 실제 코드에서는 제한이 없습니다.)

a=4이므로 Cx의 범위는 4와 x사이 입니다. Cx의 지수는 음수이므로 Cx가 클수록 우항의 값은 반비례. 따라서 오차는

위와 같습니다.

def sqrt(x: float, n: int):
	# 리턴값: 근사값, 최소 오차, 최대 오차

	_n = n if n > 4 else 4

	results = [0] * (_n+2)
	results[0] = 2		# 0차 다항식의 값은 2

	# 팩토리얼 계산
	facts = [0] * (_n+2)
	facts[1] = 1
	for k in range(2, _n+2):
		facts[k] = facts[k-1] * k

	# 1/2 - x에 대한 합 계산
	g_sum = [0] * (_n+2)
	g_sum[0] = 0.5
	for k in range(1, _n+2):
		g_sum[k] = g_sum[k-1] * (1/2 - k)

	# 테일러 다항식 계산
	for k in range(1, _n+2):
		results[k] = results[k-1] + (
			g_sum[k-1] * (((x-4)**k)/(facts[k] * (4**(k-1)) * 2))
		)

	# 오차범위
	o_x = abs(((x-4)**(n+1) / facts[n+1]) * g_sum[n] * x**(0.5-(n+1)))
	o_4 = abs(((x-4)**(n+1) / facts[n+1]) * g_sum[n] * 4**(0.5-(n+1)))

	# 오차범위 계산
	if x >= 4:
		return results[n], o_x, o_4
	else:
		return results[n], o_4, o_x

if __name__ == "__main__":
	x, n = map(int, input().split())
	ans, min_o, max_o = sqrt(x, n)
	print(f'루트 {x}, 차수: {n}')
	print(f'값: {ans}')
	print(f'최소 오차: {min_o}')
	print(f'최대 오차: {max_o}')
	print(f'실제 오차: {abs(ans - x**(0.5))}')
루트 5, 차수: 2
값: 2.234375
최소 오차: 0.001118033988749895
최대 오차: 0.001953125
실제 오차: 0.001692977499789805

실제 오차가 최소 최대 오차 범위 내에 있는 것을 확인할 수 있습니다.

이렇게 해서 테일러 급수과 관련된 기본 지식의 리뷰를 마쳤습니다. 무한 미분가능한 식을 전개해서 근사값을 구할 수 있는 테일러 급수는 나름대로 공부해 볼 만한 수학적 지식이라고 생각합니다. 테일러 급수 공부를 하면서 덕분에 그동안 까먹고 있었던 여러 미적분 공식들도 다시 돌아보는 기회를 가지게 되었습니다. 테일러 급수 시리즈는 여기서 끝이 나지만 아마 언젠간 추가적인 내용을 들고 포스팅 할 지도 모르겠습니다.

반응형