수치해석에서의 오일러 메소드
메소드 1
$D \subset \mathbb{R}^2$ 에서 정의된 연속함수 $f$ 에 대해 초기값 문제 $\begin{cases} y ' = f(x,y) \\ y( x_{0} ) = Y_{0} \end{cases}$ 가 주어져 있다. 구간 $(a,b)$ 을 $a \le x_{0} < x_{1} < \cdots < x_{n} < \cdots x_{N} \le b$ 와 같은 노드 포인트들로 쪼갰다고 하자. 특히 충분히 작은 $h > 0$ 에 대해 $x_{j} = x_{0} + j h$ 이라고 하면 초기값 $y_{0} \simeq Y_{0}$ 에 대해 $$ y_{n+1} = y_{n} + h f ( x_{n} , y_{n} ) $$
설명
오일러 메소드는 개념적으로 아주 간단한 방법이지만 수치해석의 핵심적인 아이디어를 보여준다. 물론 지금에 와서는 여러가지 문제가 많지만, 반대로 말해 개선의 여지 또한 많은 방법이다. 그래서 오일러 메소드 그 자체가 중요하다기 보다는 유도과정을 유심히 보아야한다.
유도
테일러 전개
$Y(x_{n+1} )$ 를 $x_{n}$ 에 대해 $2$ 차항까지 테일러 전개하면 $$ Y ( x_{n+1} ) = Y ( x_{n} ) + ( x_{n+1} - x_{n}) y ' ( x_{n} ) + {{( x_{n+1} - x_{n})^2} \over {2}} Y’’ ( \xi_{n} ) $$ 정리하면 $$ Y ( x_{n+1} ) = Y ( x_{n} ) + h y ' ( x_{n} ) + {{h^2} \over {2}} Y’’ ( \xi_{n} ) $$ 인데, 여기서 오차항 $\displaystyle {{h^2} \over {2}} Y’’ ( \xi_{n} )$ 을 버리면 $$ y_{n+1} = y_{n} + h f ( x_{n} , y_{n} ) $$
■
테일러 전개를 통한 유도에서 바로 알 수 있는 것은 $h$ 가 작아지면 오차도 줄어든다는 것이다. 또한 유도과정에서 테일러 근사가 꼭 $2$ 차여야하는 이유는 딱히 없기 때문에, 차수를 올리면 오차가 줄어들 것이다.
수치적 적분
$[x_{n} , x_{n+1}]$ 에서 $Y’(t) = f (t, Y(t))$ 의 정적분은 $$ \int_{x_{n}}^{x_{n+1}} f(t,Y(t)) dt = Y(x_{n+1}) - Y(x_{n}) $$ 약간의 오차가 있지만 수치적인 적분을 통해 $\displaystyle \int_{x_{n}}^{x_{n+1}} f(t,Y(t)) dt \simeq h f(x_{n} , Y(x_{n}) ) $ 이므로, $$ y_{n+1} - y_{n} = h f ( x_{n} , y_{n} ) $$
■
구분구적법의 아이디어를 생각해보면 이 역시 $h$ 가 작아질수록 오차가 작아짐을 짐작할 수가 있다. 그림에서 보다시피 실제 적분값과 수치적으로 구한 값의 차이가 꽤 큰데, 사다리꼴 메소드나 심슨 메소드를 쓰면 오차가 줄어들것이다.
구현
아래는 R로 작성된 코드다.
Euler<-function(f,Y\_0,a,b,h=10^(-3))
{
Y <- t(Y\_0)
node <- seq(a,b,by=h)
for(x in node)
{
Y<-rbind(Y,Y[length(Y[,1]),]+h*f(x,Y[length(Y[,1]),]))
}
return(Y)
}
f<-function(x,y) {y}
out<-Euler(f,seq(1,1,len=100),0,2)
out[,1]
g<-function(x,y) {1/(1+x^2) + - 2*(y^(2))}
out<-Euler(g,seq(0,0,len=100),0,2,h=0.2)
out[,1]
Atkinson. (1989). An Introduction to Numerical Analysis(2nd Edition): p341. ↩︎