지난 포스팅에서 랜덤 워크를 정의하고, 앙상블 평균의 개념을 도입하여 특정한 값을 정의하고 계산하는 방법에 대해서 알아 보았습니다. 또한 확률 밀도 함수를 정의하고, 확률 밀도 함수로 부터 경로의 함수로 주어지는 특정한 함수의 앙상블 평균을 구하는 방법, 또한 확률 밀도 함수의 스텝에 따른 변화를 기술해 주는 주방정식에 대해서도 설명하였습니다. 지난 포스팅을 읽지 않으신 분이라면, 지난 포스팅을 먼저 읽고 이 다음 내용을 읽으시길 권장합니다.
https://studyingrabbit.tistory.com/89
무작위 걸음(랜덤 워크 random walk) 101 : 파이썬 프로그램으로 구현
랜덤 워크 무작위 걸음(랜덤 워크 Random Walk)는 대표적인 확률과정(stochastic process)의 예시로, 연속적인 무작위 수에 의해서 결정되는 확률 공간에서의 "움직임의 경로"에 대해서 다룹니다. (위 첫
studyingrabbit.tistory.com
https://studyingrabbit.tistory.com/90
무작위 걸음(랜덤 워크 random walk) 102 : 앙상블 평균과 몬테 카를로 시뮬레이션
지난 포스팅 https://studyingrabbit.tistory.com/89 무작위 걸음(랜덤 워크 random walk) 101 : 파이썬 프로그램으로 구현 랜덤 워크 무작위 걸음(랜덤 워크 Random Walk)는 대표적인 확률과정(stochastic proces..
studyingrabbit.tistory.com
이번 포스팅에서는 주방정식을 활용하여 확률 밀도 함수의 변화에 대해서 좀 더 알아 보도록 하겠습니다. 확률 밀도 함수는 그 자체로도 매우 중요할 뿐 아니라, 랜덤 워크 스텝(의 증가)에 따른 확률 밀도 함수의 변화에 대한 직관을 구체적인 경우의 예시를 통해서 키우는 것은 랜덤 워크 혹은 더 나아가 확률 과정(stochastic process)에 대해 공부하는데 필수적인 요소이기 때문입니다.
확률 밀도 함수와 주방정식 복습
확률 밀도 함수는 특정한 위치, 특정한 스텝에서 입자(랜덤 워커)를 발견할 확률로 정의 됩니다. 혹은 특정한 위치, 특정한 스텝에 입자(랜덤 워커)가 존재할 확률이라고도 볼 수 있습니다. 여기서의 확률은 앙상블 평균으로 정의되는데,
와 같습니다. 모든 가능한 랜덤 워크 경로 중에서
으로 주어집니다. 초기 상태(
주방정식의 선형성
서로 다른 두 확률 밀도 함수
으로 정의할 수 있습니다. 여기서
를 더하면, 좌변은
가 됩니다. 이 값은 정의에 따라서
방정식이 해에 대해서 선형성을 갖고 있다면, 해를 구하거나 방정식의 해를 유추할 때 매우 편리 합니다. 복잡한 초기 조건이 주어졌을 때, 만일 이 초기 조건을 여러개의 쉬운 초기 조건의 합으로 표현할 수 있다면, 각 쉬운 초기 조건에 대해서 해를 먼저 구하고, 각각 구한 해를 전체 더하면 이 해는 복잡한 초기 조건에 대한 해가 되기 때문입니다.
구체적인 초기 확률 밀도 함수에 대해서 주방정식을 적용하여 임의의 스텝에서 확률 밀도 함수를 구해 보도록 하겠습니다.
벡터와 행렬을 이용한 표현
주방정식은
와 같이 정의 하도록 하겠습니다.
로 표현하도록 하겠습니다. "양쪽 방향으로 뻗어나가는 무한차원 벡터"를 생각하면 됩니다. 이에 대한 수학적인 엄밀함은 차치해 두고, 직관적인 방식으로 이를 이해하도록 하겠습니다. 이 벡터 표현법을 통해
여기서, 행렬
가 됩니다. 행렬
와 같습니다. 행렬 원소의 대부분은 0인데, 대각성분에서 행이나 열 방향으로 1만큼 차이나는 성분에서의 원소의 값은
이 됩니다.
1.
가장 간단한 초기 확률 밀도 함수 입니다. 원점에 모든 확률이 존재합니다. 이는 지금까지 우리가 해 왔던, 원점에서 시작하는 랜덤 워크와 동일 합니다. 주방정식에 따라서 임의의 스텝
가 됩니다. 여기서

2.
이번에는

3. 2차원 격자 공간에서의 주방정식
이번에는 차원을 하나 높이겠습니다. 2차원을 다룰 텐데,
로 주어집니다.
가 됩니다. 여기서

초기 조건
임의의
입니다. 이 식을 이용하여

(위 그래프의
결과는 위 그래프와 같습니다. 랜덤 워크의 스텝

이번에는 초기 확률 밀도 함수가 공간상의 두 곳에서 국소화 된 경우를 생각했습니다. 초기 조건은
위에서와 마찬가지로

(위 그래프의
와 같이 주어집니다.
위 결과는
가 됩니다.
이 성립합니다. 앙상블 평균을
가 됩니다. 여기서
위 결과를 일반화 하면, 임의의
치우친 랜덤 워크의 주방정식
위에서의 랜덤 워크는 "치우치지 않은" 랜덤 워크 였습니다. 즉, 이동할 수 있는 모든 방향으로 확률 밀도 함수가 동일한 비율로 그 다음 스텝으로 전파 되는 것 입니다. 1차원 정수 격자 공간에서
과 같이 나타낼 수 있습니다. 일반적으로
2차원 정수 격자 랜덤 워크의 예시로 들면, 오른쪽-왼쪽으로 전파할 때, 그 비율을 (예를들면)

위 애니메이션에서 볼 수 있든, 하늘색 원의 전체적인 움직임(평균)은 오른쪽 위를 향하고 있습니다. 이 처럼 치우쳐진 랜덤 워크를 주방정식의 "숫자 조절"을 통해서도 구현할 수 있습니다.
아래는 위 애니메이션을 구현하기 위한 파이썬 프로그램 코드 입니다. 좀 더 공부를 하고 싶으신 분은 아래 코드를 이용하여 이것 저것 시도해 볼 수 있습니다.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
def update(num, list_list_x, list_list_y, list_list_value):
Z = np.array([list_list_x[num], list_list_y[num]]).T
point.set_offsets(Z)
point.set_sizes(np.array(list_list_value[num]).T)
def return_index(x,y,L):
return 2*L*y + x
def return_x_y(index, L):
y, x = divmod(index, 2*L)
return x-L, y-L
L = 15
N = 2*L * 2*L
A = np.zeros([N, N])
for x in range(2*L):
for y in range(2*L):
x_l, y_l = x-1, y
x_r, y_r = x+1, y
x_t, y_t = x, y+1
x_b, y_b = x, y-1
a = return_index(x, y, L)
if 0<=x_l < 2*L and 0<=y_l < 2* L:
b = return_index(x_l, y_l, L)
A[a,b] = 0.40
A[b,a] = 0.10
if 0<=x_t < 2*L and 0<=y_t < 2* L:
b = return_index(x_t, y_t, L)
A[a,b] = 0.2
A[b,a] = 0.30
p = np.zeros(N)
a = return_index(L, L, L)
p[a] =1
list_list_x, list_list_y, list_list_value =[], [], []
list_list_x.append([0])
list_list_y.append([0])
list_list_value.append([1.0*2000])
S = 14
for iteration in range(1, S):
p = np.matmul(A, p)
list_x, list_y, list_value = [], [], []
for index, pp in enumerate(p):
if not pp==0.0:
x,y = return_x_y(index, L)
list_x.append(x)
list_y.append(y)
list_value.append(pp*2000)
list_list_x.append(list_x)
list_list_y.append(list_y)
list_list_value.append(list_value)
fig = plt.figure(figsize=(8, 8))
ax = plt.axes()
ax.grid()
ax.set_xlim(-L, L)
ax.set_ylim(-L, L)
ax.set_xlabel('x')
ax.set_ylabel('y')
point = ax.scatter([], [], s=50, color = 'dodgerblue')
ani = animation.FuncAnimation(fig, update, S, fargs=(list_list_x, list_list_y, list_list_value), interval=500, blit=False)
#ani.save('2dim_2.gif', writer=animation.PillowWriter(fps=2))
plt.show()