수치해석
재료공학도를 위한 수치해석
1. 학습 목표
이번 강의가 끝나면 다음을 할 수 있어야 한다.
- 접선의 방정식으로 Newton-Raphson 반복식을 유도할 수 있다.
- 함수와 도함수를 이용하여 다음 근삿값을 계산할 수 있다.
- 초기값이 수렴 결과에 미치는 영향을 설명할 수 있다.
- 잔차와 근의 위치 오차를 구분할 수 있다.
- Newton-Raphson 방법을 Python으로 구현할 수 있다.
2. Newton-Raphson 방법
이분법은 근을 포함하는 구간을 항상 유지하므로 안정적이지만, 구간의 길이가 한 번에 절반씩만 줄어든다. Newton-Raphson 방법은 현재점에서 함수의 접선을 만들고, 접선이 $x$축과 만나는 점을 다음 근삿값으로 사용한다.

2.1. 접선을 이용한 반복식 유도
현재 근삿값을 $x_{k}$이라고 하자. 점 $(x_k,f(x_k))$에서 접선의 기울기는 $f’(x_k)$이므로 접선의 방정식은 다음과 같다.
\[y-f(x_k)=f'(x_k)(x-x_k)\]이 접선이 $x$축과 만나는 점을 $x_{k+1}$이라고 하면 $y=0$이므로
\[-f(x_k)=f'(x_k)(x_{k+1}-x_k)\]이다. 이를 $x_{k+1}$에 대해 정리하면 Newton-Raphson 반복식을 얻는다.
\[\boxed{ x_{k+1}=x_k-\frac{f(x_k)}{f'(x_k)} }\]현재점에서 계산한 보정량을 $\Delta x_k$이라고 쓰면
\[\Delta x_k=-\frac{f(x_k)}{f'(x_k)}, \qquad x_{k+1}=x_k+\Delta x_k\]으로도 표현할 수 있다.
2.2. 알고리듬
- 함수 $f(x)$와 도함수 $f’(x)$를 준비한다.
- 초기값 $x_0$와 허용오차를 정한다.
- $f(x_k)$과 $f’(x_k)$을 계산한다.
- $f’(x_k)=0$이거나 0에 매우 가까우면 계산을 중단한다.
- 반복식으로 $x_{k+1}$을 구한다.
- 종료 조건을 만족하면 계산을 마치고, 그렇지 않으면 반복한다.
주로 다음과 같은 종료 조건을 사용한다.
\[|f(x_k)|\leq\mathrm{tol}_f\]또는
\[|x_{k+1}-x_k|\leq\mathrm{tol}_x\]** (중요) 무한 반복을 막기 위해 최대 반복 횟수도 함께 설정한다.
3. 예제: $x^2=2$
방정식 $x^2=2$의 두 해는 $x=\pm\sqrt{2}$이다. 이를 근 찾기 문제로 바꾸면
\[f(x)=x^2-2, \qquad f'(x)=2x\]이다. 따라서 반복식은
\[x_{k+1} =x_k-\frac{x_k^2-2}{2x_k} =\frac{1}{2}\left(x_k+\frac{2}{x_k}\right)\]이다.
3.1. 손으로 계산하기
초기값을 $x_0=1$로 정하고 반복해보자.
| $k$ | $x_k$ | $ | f(x_k) | = | x_k^2-2 | $ |
|---|---|---|---|---|---|---|
| 0 | $1.000000000$ | $1.000000000$ | ||||
| 1 | $1.500000000$ | $0.250000000$ | ||||
| 2 | $1.416666667$ | $0.006944444$ | ||||
| 3 | $1.414215686$ | $6.0073\times 10^{-6}$ | ||||
| 4 | $1.414213562$ | $4.51\times 10^{-12}$ |
첫 번째 반복은 다음과 같다.
\[x_1 =1-\frac{1^2-2}{2\times1} =1.5\]두 번째 반복은 다음과 같다.
\[x_2 =1.5-\frac{1.5^2-2}{2\times1.5} =1.416666666\ldots\]허용 잔차를 $10^{-10}$으로 정하면 네 번째 반복에서
\[|f(x_4)|<10^{-10}\]이므로 계산을 종료할 수 있다.
3.2. 잔차와 근의 오차
$|f(x_n)|$은 근삿값을 함수에 대입했을 때 0에서 얼마나 떨어져 있는지를 나타내는 잔차(residual)이다.
\[\text{잔차}=|f(x_n)|\]참근 $x^*$를 알고 있을 때 계산할 수 있는 근의 절대 오차는 다음과 같다.
\[\text{근의 절대 오차}=|x^*-x_n|\]수치해석에서는 참근을 모르는 경우가 많으므로 잔차 또는 연속된 두 근삿값의 차이를 종료 조건으로 사용한다. 잔차와 근의 위치 오차는 서로 같은 값이 아니다.
3.3. Python 구현
다음 함수는 근의 근삿값, 반복 횟수와 반복 기록을 반환한다.
def newton_raphson(f, df, x0, tol=1e-10, max_iter=50):
x = float(x0)
history = [x]
for iteration in range(max_iter+1):
fx = f(x)
if abs(fx) <= tol:
return x, iteration, history
if iteration == max_iter:
break
dfx = df(x)
if abs(dfx) < 1e-14:
raise ZeroDivisionError("도함수가 0에 너무 가까워 계산할 수 없습니다.")
x = x-fx/dfx
history.append(x)
raise RuntimeError("최대 반복 횟수 안에 수렴하지 않았습니다.")
$x^2-2=0$에 적용해보자.
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return x**2-2
def df(x):
return 2*x
root, iterations, history = newton_raphson(f, df, x0=1.0)
print("root:", root)
print("f(root):", f(root))
print("iterations:", iterations)
반복에 따른 근삿값과 잔차의 변화를 그려보자.
history = np.array(history)
residuals = np.abs(f(history))
k = np.arange(len(history))
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
axes[0].plot(k, history, "o-")
axes[0].axhline(np.sqrt(2), color="black", linestyle="--",
label=r"$\sqrt{2}$")
axes[0].set_xlabel("iteration")
axes[0].set_ylabel(r"$x_n$")
axes[0].grid()
axes[0].legend()
axes[1].semilogy(k, residuals, "o-")
axes[1].set_xlabel("iteration")
axes[1].set_ylabel(r"$|f(x_n)|$")
axes[1].grid()
plt.tight_layout()
plt.show()
4. 초기값과 수렴
Newton-Raphson 방법은 초기값이 필요하며, 초기값에 따라 결과가 달라질 수 있다.
- $x_0=1$로 시작하면 $+\sqrt{2}$에 수렴한다.
- $x_0=-1$로 시작하면 $-\sqrt{2}$에 수렴한다.
- $x_0=0$이면 $f’(0)=0$이므로 반복식의 분모가 0이 되어 계산할 수 없다.
for x0 in [1.0, -1.0]:
root, iterations, history = newton_raphson(f, df, x0)
print("x0 =", x0, "root =", root, "iterations =", iterations)
Newton–Raphson 방법은 좋은 초기값에서 시작하면 단순근 근처에서 매우 빠르게 수렴한다. 그러나 다음과 같은 경우에는 수렴하지 않을 수 있다.
- 반복 중 도함수가 0 또는 매우 작은 값이 되는 경우
- 초기값이 근에서 너무 멀리 떨어진 경우
- 반복값이 함수의 정의역을 벗어나는 경우
- 여러 근 중 예상하지 않은 근으로 이동하는 경우
따라서 그래프를 먼저 그리거나 이분법으로 근이 있는 구간을 확인한 뒤 초기값을 정하면 도움이 된다.
5. 적용 예제
5.1. $x^2=3$
\[f(x)=x^2-3, \qquad f'(x)=2x\] \[x_{n+1}=x_n-\frac{x_n^2-3}{2x_n}\]양의 근을 구하려면 양의 초기값을 사용해보자.
5.2. $x^4=2$
\[f(x)=x^4-2, \qquad f'(x)=4x^3\] \[x_{n+1}=x_n-\frac{x_n^4-2}{4x_n^3}\]$x_0=0$에서는 도함수가 0이므로 시작할 수 없다.
5.3. $\ln x=1$
\[f(x)=\ln x-1, \qquad f'(x)=\frac{1}{x}\] \[x_{n+1} =x_n-\frac{\ln x_n-1}{1/x_n} =x_n-x_n(\ln x_n-1)\]로그 함수의 정의역 때문에 모든 반복값은 $x_n>0$이어야 한다. 해는 $x=e$이다.
5.4. $\cos x=0.3$
\[f(x)=\cos x-0.3, \qquad f'(x)=-\sin x\] \[x_{n+1} =x_n-\frac{\cos x_n-0.3}{-\sin x_n}\]이 방정식은 주기성 때문에 여러 근을 갖는다. 초기값에 따라 서로 다른 근으로 수렴할 수 있으며, $\sin x_n=0$인 점에서는 반복식을 계산할 수 없다.
6. 이분법과 비교
| 항목 | 이분법 | Newton–Raphson 방법 |
|---|---|---|
| 필요한 정보 | $f(x)$와 근을 둘러싼 구간 | $f(x)$, $f’(x)$와 초기값 |
| 한 단계의 계산 | 중점과 함수값 | 함수값과 도함수 |
| 수렴 특성 | 느리지만 안정적 | 좋은 초기값에서는 매우 빠름 |
| 주요 주의점 | 연속성과 부호 변화가 필요 | 도함수 0과 초기값에 주의 |
| 근을 포함하는 구간 | 반복 내내 유지 | 일반적으로 유지하지 않음 |
7. 정리
- Newton-Raphson 방법은 현재점의 접선과 $x$축의 교점을 다음 근삿값으로 사용한다.
- 반복식은 $x_{k+1}=x_k-f(x_k)/f’(x_k)$이다.
- 좋은 초기값에서 단순근에 가까우면 매우 빠르게 수렴할 수 있다.
-
잔차 $ f(x_k) $와 근의 위치 오차 $ x^*-x_k $는 서로 다르다. - 도함수가 0에 가깝거나 반복값이 정의역을 벗어나면 실패할 수 있다.
8. 연습 문제
강의에서 배운 식을 직접 적용하는 기초 문제이다.
-
다음 빈칸을 채워라.
\[x_{k+1}=x_k-\frac{( )}{( )}\]Newton-Raphson 방법은 현재점에서 함수의 ( )을 이용한다.
-
$f(x)=x^2-2$일 때 $f’(x)$를 구하고 $x_0=1$에서 $x_1$을 계산하라.
-
$f(x)=x^2-3$이고 $x_0=2$일 때 $x_1$과 $x_2$를 계산하라.
-
다음 함수의 도함수를 구하고 Newton-Raphson 반복식을 작성하라.
- $f(x)=x^3-8$
- $f(x)=\ln x-2$
-
다음 값 중 $f(x)=x^2-2$의 Newton-Raphson 초기값으로 바로 사용할 수 없는 값을 고르고 이유를 설명하라.
\[-1,\qquad0,\qquad1\] -
$x^2-2=0$에서 $x=1.5$일 때 잔차 $ f(x) $와 참근을 이용한 절대 오차 $ \sqrt{2}-x $를 각각 구하라. 두 값이 같은지도 확인하라. -
강의의
newton_raphson함수를 사용하여 $x^2-3=0$의 양의 근을 구하라.def f(x): return x**2-3 def df(x): return 2*x root, iterations, history = newton_raphson(f, df, x0=2.0) print(root) print(iterations)계산 결과를 np.sqrt(3)과 비교하라.
-
Newton-Raphson 방법과 이분법을 비교하여 다음 빈칸을 채워라.
- 도함수가 필요한 방법: ( )
- 근을 포함하는 시작 구간이 필요한 방법: ( )
- 좋은 초기값에서 일반적으로 더 빠른 방법: ( )