여러 함수들의 적분은 간단한 꼴로 나타낼 수 없다. 예를 들어, sinx2\sin{x^2}1lnx\frac{1}{\ln{x}}와 같은 함수는 그 적분을 간단히 나타낼 수 없다. 이와 같이 적분해야 하는 함수의 적분을 찾기 어려울 때, 주어진 부분구간에서 함수 ff와 비슷한 함수로 대체한 다음 이 함수의 적분값을 더하여 함수 ff의 적분값을 구하는 방법을 수치적분(numerical integration)이라고 한다. 수치적분은 대부분의 경우 매우 많은 양의 계산을 필요로 한다. 본 보고서에서는 몇 가지의 대표적인 수치적분 방법을 알아보고, 이를 python을 이용하여 구현한다.

구분구적법

가장 간단한 수치적분 방법 중 하나는 구분구적법이다. 함수의 그래프를 매우
작은 직사각형으로 잘게 나누어 그 사각형들의 넓이의 합을 이용하여
정적분을 구하는 방법을 구분구적법이라고 한다.

구현

rectangle1rectangle2는 각각 아래 그림에서의 a와 b를 코드로 구현한 함수이다.

def rectangle(n, a, b):
    S = 0.0
    h = (b - a) / n

    for i in range(1, n + 1):
        S += f(a + (i - 1) * h) * h

    return S

def rectangle2(n, a, b):
    S = 0.0
    h = (b - a) / n

    for i in range(1, n + 1):
        S += f(a + i * h) * h

    return S

구분구적법

사다리꼴 공식

사다리꼴 공식은 우리가 앞서 학습한 구분구적법에서 직사각형 대신
사다리꼴을 적용한 방법이다. 함수 ff를 구간 [a,b][a,b]에서 적분하는 경우를
생각하자. 구간 [a,b][a,b]nn등분한 분할을 생각하자.
a=x0<X1<x2<<xn1<xn=ba= x_0 < X_1 < x_2 < \cdot < x_{n-1} < x_n = b에서, 부분구간의 길이는
Δx=ban\Delta x = \frac{b-a}{n}이다. yi=f(xi)y_i = f(x_i )일 때, ii번째 구간의
사다리꼴 넓이는
Δx(Yi1+yi2)=Δx2(yi1+yi)\Delta x \left( \frac{Y_{i-1} + y_i}{2} \right)= \frac{\Delta x}{2}\left( y_{i-1}+y_i \right)이다.
Δx\Delta x를 높이로 삼는다면 수직으로 놓인 두 변의 평균과 곱한 값이
넓이이다. 곡선 아래 넓이는 다음 식과 같이 모든 사다리꼴의 넓이를 더하여 근사값을 구한다.

T=12(y0+y1)Δx+12(y1+y2)Δx++12(yn2+yn1)Δx=Δx2(y0+2y1+2y2++2yn1+yn)\begin{aligned} T &= \frac{1}{2} (y_0 + y_1) \Delta x + \frac{1}{2} (y_1 + y_2) \Delta x + \cdots + \frac{1}{2} (y_{n-2} + y_{n-1}) \Delta x \\ &= \frac{\Delta x}{2} (y_0 + 2y_1 + 2y_2 + \cdot + 2y_{n-1} + y_n) \end{aligned}

따라서 다음과 같이 적분의 근사값을 구할 수 있다.

abf(x)dxΔx2(y0+2y1+2y2++2yn1+yn)\begin{aligned} \int_{a}^{b} f(x)dx \approx \frac{\Delta x}{2} (y_0 + 2y_1 + 2y_2 + \cdots + 2y_{n-1} + y_n) \end{aligned}

구현

앞에서 구현한 구분구적법과 비슷한 방법을 이용하여 사다리꼴 공식을 python을 이용하여 구현할 수 있었다.

def trapezoidal(n, a, b):
    S = 0.0
    h = (b - a) / n

    for i in range(1, n):
        S += f(a + i * h)

    S = (f(a) + 2 * S + f(b)) * h / 2.0
    return S

심프슨 1/3 공식

세 점을 지나는 포물선을 구하여 적분한 값을 더하여 근사값을 구하는 것을 심프슨 공식이라고 한다. 세 점 (x0,y0),(x1,y1),(x2,y2)(x_{0}, y_{0}),(x_{1}, y_{1}), (x_{2}, y_{2})를 지나는 포물선을 생각하자. x0=h,x1=0,x2=hx_0 = -h, x_1 = 0, x_2 = h이라고 하자. 이때 h=Δx=banh=\Delta x = \frac{b-a}{n}이 된다. 포물선의 방정식을

y=Ax2+Bx+C\begin{aligned} y = Ax^2 + Bx + C \end{aligned}

라고 하면 이 포물선의 아래 면적은

Ap=hh(Ax2+Bx+C)dx=20h(Ax2+C)dx=2[13Ax3+Cx]0h=h3(2Ah2+6C)\begin{aligned} A_p &= \int_{-h}^{h} \left( Ax^2 + Bx + C \right) dx \\ &= 2\int_{0}^{h} \left( Ax^2 + C \right) dx \\ &= 2 \left[ \frac{1}{3} Ax^3 + Cx \right]^h_0 \\ &= \frac{h}{3} (2Ah^2 + 6C) \end{aligned}

세 점 (h,y0),(0,y1),(h,y2)(-h, y_{0}),(0, y_{1}), (h, y_{2})가 포물선 위에
있으므로

y0=Ah2Bh+C,y1=C,y2=Ah2+Bh+CC=y1,2Ah2=y0+y22y1y_0 = Ah^2 - Bh + C, y_1 = C, y_2 = Ah^2 + Bh + C \\ \therefore C = y_1, 2Ah^2 = y_0 + y_2 - 2y_1

따라서 위에서 구한 넓이는

Ap=h3(2Ah2+6C)=h3((y0+y22y1)+6y1)=h3(y0+4y1+y2)\begin{aligned} A_p &= \frac{h}{3} (2Ah^2 + 6C) \\ &= \frac{h}{3} ((y_0 + y_2 - 2y_1) + 6y_1) \\ &= \frac{h}{3} (y_0 + 4y_1 + y_2) \end{aligned}

마찬가지로 (x2,y2),(x3,y3),(x4,y4)(x_{2}, y_{2}),(x_{3}, y_{3}), (x_{4}, y_{4})를 지나는 포물선 아래 넓이는

h3(y2+4y3+y4)\begin{aligned} \frac{h}{3} (y_2 + 4y_3 + y_4) \end{aligned}

따라서 다음 식과 같이 근사값을 구할 수 있다.

abf(x)dxh3(y0+4y1+y2)+h3(y2+4y3+y4)++h3(yn2+4yn1+yn)=h3(y0+4y1+2y2+4y3+2y4++4yn1+yn\begin{aligned} \int_a^b f(x)dx &\approx \frac{h}{3} (y_0 + 4y_1 + y_2) + \frac{h}{3} (y_2 + 4y_3 + y_4) + \cdots + \frac{h}{3} (y_{n-2} + 4y_{n-1} + y_n) \\ &= \frac{h}{3}(y_0 + 4y_1 + 2y_2 + 4y_3 + 2y_4 + \cdots + 4y_{n-1} + y_n \end{aligned}

구현

짝수항을 다 더하고, 홀수항을 모두 더하여 그 둘의 합을 구하는 방법으로 간단하게 심프슨 1/3공식을 구현할 수 있었다.

def simpson(n, a, b):
    h = (b - a) / (2 * n)
    S1 = 0.0
    S2 = f(a + h)

    for i in range(2, 2 * n, 2):
        S1 += f(a + i * h)
        S2 += f(a + (i + 1) * h)
profile
KAIST 24

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

유익한 글 잘 봤습니다, 감사합니다.

답글 달기