일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- auto-encoder
- 신경망
- 벡터 해석
- 자바
- BST
- 강화학습
- 델
- 딕셔너리
- 이진탐색트리
- Class
- 선적분
- 함수
- cURL
- 딥러닝
- 계단 오르기
- 회로이론
- 미분 방정식
- 파이썬
- Python
- 백트래킹
- 소행성
- dictionary
- 벡터해석
- 코드업
- 2P1L
- Asteroid RL
- 최단 경로
- java
- 피보나치 수열
- 자료형
- Today
- Total
Zeta Oph's Study
(연립) 미분 방정식의 수치적 해법 (2) : 룽게-쿠타 방법(Runge-Kutta Method)과 로트카-볼테라 방정식(Lotka-Volterra Equation) 본문
(연립) 미분 방정식의 수치적 해법 (2) : 룽게-쿠타 방법(Runge-Kutta Method)과 로트카-볼테라 방정식(Lotka-Volterra Equation)
Zeta Oph 2023. 4. 1. 20:41
이 글에서는 미분 방정식의 수치적 해법 중 룽게-쿠타 방법(Runge-Kutta Method)에 대해 설명하겠습니다.
룽게-쿠타 방법(Runge-Kutta Method)
룽게-쿠타 방법은 미분 방정식의 수치적 해법 중 하나로서, 2차 룽게-쿠타 방법, 4차 룽게-쿠타 방법 등이 있습니다. 여기서는 주로 많이 쓰이는 4차 룽게-쿠타 방법(RK4)에 대해 다루도록 하겠습니다.
룽게-쿠타 방법은 다변수 함수의 테일러 전개로부터 유도되는 방법입니다. 하지만, 이 글에서는 룽게-쿠타 방법의 유도는 다루지 않고, 간단히 4차 룽게-쿠타 방법의 알고리즘만 소개하도록 하겠습니다.
우리가 풀어야 할 미분 방정식을 아래와 같이 설정합니다.
$$\frac{dy}{dt}=f(t, y),\quad y(t_0)=y_0$$
$t_{i+1}=t_i+h$로 설정하고, 아래와 같이 값을 정의할 수 있습니다.
$$k_1=f(t_i, y_i)$$
$$k_2=f(t_i+\frac{1}{2}h, y_i+\frac{1}{2}hk_1)$$
$$k_3=f(t_i+\frac{1}{2}h, y_i+\frac{1}{2}hk_2)$$
$$k_4=f(t_i+h, y_i+hk_3)$$
위와 같이 $k_1, k_2, k_3, k_4$를 정의하면, 아래와 같은 근사를 사용할 수 있습니다.
$$y_{i+1}=y_i+\frac{1}{6}h(k_1+2k_2+2k_3+k_4)$$
이와 같은 근사를 사용하여 함수값을 찾는 방법이 4차 룽게-쿠타 방법(RK4)입니다.
연립 미분 방정식의 풀이
미지수가 여러개인 미분 방정식을 여러개 모아놓은 system을 연립 미분 방정식이라고 합니다. 연립 미분 방정식의 수치해법은 미지수가 1개인 일반적인 미분 방정식의 수치해법과 크게 다르지 않습니다.
아래와 같은 $m$개의 미분 방정식을 생각해봅시다.
$$y^{'}(x)_{1}=f_{1}(x, y_1, ... , y_m), \quad y_1(x_0)=\alpha_1$$
$$y^{'}(x)_{2}=f_{2}(x, y_1, ... , y_m), \quad y_2(x_0)=\alpha_2$$
$$\vdots$$
$$y^{'}(x)_{m}=f_{m}(x, y_1, ... , y_m), \quad y_m(x_0)=\alpha_m$$
이를 벡터로 표기한다면,
$$\mathbf{y^{'}}(x)=\mathbf{f}(x, \mathbf{y}(x)), \quad \mathbf{y}(x)=\mathbf{\alpha}$$
와 같이 표기할 수 있습니다. 이때
$$\mathbf{y}(x)=\left \{\begin{array}{cc} y_{1}(x) \\ y_{2}(x) \\ \vdots \\ y_{m}(x) \end{array} \right \}, \; \mathbf{f}=\left \{\begin{array}{cc} f_{1}(x, y_1, ... , y_m) \\ f_{2}(x, y_1, ... , y_m) \\ \vdots \\ f_{m}(x, y_1, ... , y_m) \end{array} \right \}, \; \mathbf{\alpha}=\left \{\begin{array}{cc} \alpha_1 \\ \alpha_2 \\ \vdots \\ \alpha_m \end{array} \right \}$$
입니다. 이렇게 된 식은 벡터가 들어간 것을 제외하면 미지수가 1개인 미분방정식과 같은 형태이므로, 벡터의 형태로 원래 우리가 알고 있는 수치적 방법을 적용하면 됩니다. 파이썬의 경우에는, float형 변수 자리에 float형 array를 사용하면 되는 것이죠.
로트카-볼테라 방정식(Lotka-Volterra Equation)
어느 생태계에서 포식자와 피식자 사이 관계를 생각해봅시다. 피식자의 수가 줄어들면, 포식자는 먹이가 줄어들어 포식자 개체수 또한 감소하게 됩니다. 그러면 피식자의 개체수가 다시 늘고, 이에 따라 포식자의 수 또한 다시 증가하고, 또 피식자의 수가 줄어들고..... 이렇게 포식자와 피식자의 개체수는 주기적으로 반복되지 않을지 의문을 가질 수 있습니다. 이에 대한, 포식자와 피식자의 개체수에 관한 미분 방정식이 바로 로트카-볼테라 방정식(Lotka-Volterra Equation)입니다.
피식자의 개체수를 $x$, 포식자의 개체수를 $y$라 합니다. 또한 피식자와 포식자 사이 상호작용으로 인한 개체수 변동에 대한 상수를 각각 $b, d$로, 피식자와 포식자 스스로에 의한 개체수 변동에 대한 상수를 각각 $a, c$로 놓습니다. 피식자와 포식자 스스로에 의한 개체수 변동은 피식자와 포식자의 개체수 $x, y$에 비례할 것이고, 피식자와 포식자 사이 상호작용으로 인한 개체수 변동은 포식자와 피식자가 마주치는 횟수, 즉 $x$와 $y$의 곱에 비례할 것임을 알 수 있습니다. 이러한 사실을 바탕으로, 미분 방정식을 기술해보면 아래와 같은 결과를 얻을 수 있습니다.
$$\frac{dx}{dt}=ax-bxy$$
$$\frac{dy}{dt}=-cx+dxy$$
이 연립 비선형 상미분 방정식이 바로 로트카-볼테라 방정식(Lotka-Volterra Equation)입니다.
코드 작성
이제 4차 룽게-쿠타 방법을 이용하여 로트카-볼테라 방정식을 풀어보도록 하겠습니다.
우선 순서도를 그려보았습니다.
위 순서도를 바탕으로 아래 코드를 작성해보았습니다.
import numpy as np
import matplotlib.pyplot as plt
a = 3
b = 2
c = 1
d = 2
def lveq(t, y):
dydt0 = a*y[0] - b*y[0]*y[1]
dydt1 = -c*y[1] + d*y[0]*y[1]
return np.array([dydt0, dydt1])
def RK4(f, h, t0, tmax, y0):
n = int((tmax - t0)/h)
t = t0
y = y0
m = len(y0)
tsol = np.zeros(n+1)
ysol = np.zeros([n+1, m])
tsol[0] = t
ysol[0, :] = y
for i in range(n):
k1 = f(t, y)
k2 = f(t+0.5*h, y+0.5*h*k1)
k3 = f(t+0.5*h, y+0.5*h*k2)
k4 = f(t+h, y+h*k3)
y = y + h*(k1 + 2*k2 + 2*k3 + k4)/6
t = t + h
tsol[i+1] = t
ysol[i+1, :] = y
return tsol, ysol
h = 0.01
t0, tmax = 0, 20
y0 = np.array([1.9, 1.7])
t, y = RK4(lveq, h, t0, tmax, y0)
plt.plot(t, y[:,0], label = r'$x$'' (prey)')
plt.plot(t, y[:,1], label = r'$y$'' (predator)')
plt.xlabel(r'$t$')
plt.ylabel(r'$x, y$'' (population)')
plt.legend()
plt.title("Lotka-Volterra Equation")
plt.show()
아래는 코드에 대한 간단한 설명입니다.
풀어야 할 방정식(이 코드의 경우는 로트카-볼테라 방정식)을 입력합니다. 함수의 범위를 t0부터 tmax까지로 설정하고, 초깃값 y0를 설정해줍니다. 설정한 범위를 길이가 h인 구간 n개로 나눕니다. 위에서 설명한 4차 룽게-쿠타 방법의 알고리즘을 바탕으로 k1, k2, k3, k4를 계산하고 이를 통해 y와 t값을 계산한 후 이를 tsol, ysol에 추가해주는 작업을 n번 반복합니다. 이렇게 얻은 tsol과 ysol을 바탕으로 그래프를 그리면 코드는 끝이 납니다.
위 코드를 실행하면 아래와 같은 그래프를 얻을 수 있습니다.
위 로트카-볼테라 방정식의 설명과 같이, 포식자 수가 증가하여 피식자 수가 감소하고, 이에 따라 포식자 수가 감소하고 피식자 수가 다시 증가하고, 또 다시 포식자 수가 증가하는 변화가 주기적으로 반복됨을 볼 수 있습니다.
로트카-볼테라 방정식의 예시로는 캐나다에서 눈신토끼와 스라소니의 관계를 예로 들 수 있습니다. 아래 1840년대부터 1930년대까지의 데이터를 보면, 피식자 눈신토끼와 포식자 스라소니의 관계는 로트카-볼테라 방정식을 따름을 알 수 있습니다.
그런데, 우리의 생활과 바로 밀접한 예시가 하나 더 있습니다. 눈치 채셨나요?
바로 코로나 19 확진자 수입니다.
로트카-볼테라 방정식은 감염병에도 적용할 수 있습니다. 피식자 대신 비감염자, 포식자 대신 감염자(전파자)를 대입하여 방정식을 적용할 수 있습니다. 그래서 실제 코로나 19 확진자 수가 계속해서 감소하거나 증가하지 않고, 아래 그래프와 같이 진동하는 것입니다.
이렇게 4차 룽게-쿠타 방법을 이용하여, 포식자와 피식자의 개체수에 관련된 비선형 연립 미분 방정식 로트카-볼테라 미분 방정식을 풀어보았습니다.
'프로그래밍' 카테고리의 다른 글
신경망의 구현 - 딥러닝 공부 (2) (1) | 2023.05.31 |
---|---|
퍼셉트론과 신경망 - 딥러닝 공부 (1) (1) | 2023.05.31 |
다항 회귀 (Polynomial Regression) (2) | 2023.05.16 |
미분 방정식의 수치적 해법 (1) : 오일러 방법(Euler's Method)과 종단속력(Terminal Velocity) (1) | 2023.04.01 |
matplotlib을 이용한 우주 거대 구조 지도 그리기 (1) | 2023.03.22 |