몬테카를로 시뮬레이션 : 함수의 적분값 구하기 (2)

luvoatiger·2020년 10월 31일
0

MonteCarloSimulation

목록 보기
3/3
post-thumbnail

지난 포스팅에서는 구간 0과 1사이에서 함수의 적분값을 수치적으로 구하는 과정을 정리했습니다. 이번에는 구간 a와 b사이에서 함수의 적분값을 수치적으로 구하는 방법을 설명하도록 하겠습니다.

배운 것을 활용하자

구간 [a,b][a, b] 사이에서 함수 g(x)g(x)를 적분하려고 합니다. 이 때, 앞에서 배운 [0,1][0, 1] 사이에서 함수 h(u)h(u)를 적분하는 방법을 어떻게 사용할 수 있을까요? 먼저 적분구간이 다르므로 구간을 맞춰줘야 할 것 같습니다. 그리고 그에 맞춰서 함수 g(x)g(x)를 어떻게 변형하면 되는지 생각해보면 될 것 같아보입니다.

즉, 함수 g(x)g(x)를 함수 h(u)h(u)로 변형하는데 다음 조건을 만족해야 합니다.

abg(x)dx=01h(u)du\int_{a}^{b}g(x)dx = \int_{0}^{1}h(u)du

함수를 변형하자

먼저 적분구간이 다르므로 이를 맞춰줍시다. 구간 [a,b][a, b]를 구간 [0,1][0, 1]로 맞추는 게 개인적으로 생각하기 더 편해서 다음 관계가 성립하는 것을 알 수 있었습니다.

u=xabau = \frac{x-a}{b-a}

따라서 함수 g(x)g(x)의 구간을 [a,b][a, b]에서 [0,1][0, 1]사이로 바꾸면 원래의 함수는 다음처럼 변형됩니다.

abg(x)dx=01g(a+[ba]u)(ba)du\int_{a}^{b}g(x)dx = \int_{0}^{1}g(a + [b - a]u)(b - a)du

여기서 uu는 표준균일분포에서 생성한 난수입니다.

예제

# integral of exp(-x^2) from a to b
def integrate_exp_negative_square(a, b, size):
    random_number = np.random.uniform(size=size)
    transformed_random_number = a + (b - a) * random_number
    exp_x_square = np.exp(-np.square(transformed_random_number))
    final_result = (b - a) * exp_x_square

    return np.mean(final_result)

manual_solution = integrate_exp_negative_square(1, 10, 1000000)
scipy_solution = integrate.quad(lambda x : math.exp(-x**2), 1, 10)
print("manual : {}, scipy : {}".format(manual_solution, scipy_solution))  
# manual : 0.13933370564933364, scipy : (0.13940279264033098, 3.928467470000696e-15)  

1,000,000개의 표준균일분포 난수 UU가 담긴 배열을 생성한 다음에 수작업으로 구한 결과와 scipy 패키지에서 구한 결과와 비슷한 것을 알 수 있습니다.

profile
시뮬레이션, 최적화이론에 관심있습니다.

0개의 댓글