[Python]미분방정식 - 테일러 급수, 오일러의 방법, 룽게-쿠타 방법
미분방정식 - 초기값 문제
- 테일러 급수
- 오일러의 방법
- 룽게-쿠타 방법
초기값 문제 Initial-Value Problem(IVP)
-
미분 방정식의 일반해를 이용, 초기조건을 이용하여 특수해 구하는 과정
-
일반해 + 초기조건 = 특수해
미분방정식
-
x’ = x + 1
-
x’ = 6t - 1
일반해
-
\(x(t) = ce^t - 1\)
-
\(x(t) = 3t^2 - t + c\)
초기조건
-
x(0) = 0
-
x(1) = 6
특수해
- \(x = e^t - 1\)
- \(x = 3t^2 - t + 4\)
오일러의 방법 실습
-
테일러 급수의 공식에서 앞에 2개의 항을 이용한 방법이다.
-
\(x(t+h) = x(t) + hx’(t)\)
예시로 오일러 방법 사용해서 초기값이 x(1) = -4
인 미분방정식 x' = 1 + x^2 + t^3
에 대한
x(2)
의 근삿값을 100단계
를 적용하여 계산하라. 라고 할때? h=(2-1)/100
로 구할 수 있죠.
그리고 공식을 적용해주면?
-
x(1) = -4
-
x(1.01) = -3.82
-
x(1.02) = …
-
x(2) = …
이런식으로 구할수 있는 것이다.
다른 예시로 실습
# 초기값 : x'(t) = x, x(0) = 1, x(t) = e^t
import matplotlib.pyplot as plt
import numpy as np
def f(t, x): # x' -> x'(t) 구하는 함수
return x # 초기값 보면 x
def Euler(a,b,x,n): # x는 x(0)
h = (b-a)/n
t = a
answerT = [t]
answerX = [x]
for k in range(0,n):
x = x+h*f(t,x) # x update -> x(t) 구함
t = t+h # t update
answerT.append(t)
answerX.append(x)
return answerT, answerX
# 초기값 : x'(t) = x, x(0) = 1, x(t) = e^t
# n = 10단계로, [0,4] 구간
n = 10
start = 0.0
end = 4.0
bX = []
bY = []
for i in range(0,n+1): # 기존 e^t 함수 그래프를 보여주기 위함
x = start + (end-start)/n*i
y = np.exp(x)
bX.append(x)
bY.append(y)
aT, aX = Euler(start, end, 1, n)
plt.plot(aT,aX, 'ro-', label='Euler\'s method')
plt.plot(bX,bY,'bo-',label='y=exp(x)')
plt.legend()
plt.show()
4차 룽게-쿠타법 RK4 실습
-
오일러랑 동일한데 미분 안하고 미분방정식을 해결한다는게 큰 특징이다.
-
\(x(t+h) = x(t) + \frac{1}{6}(K_1 + 2K_2 + 2K_3 + K_4)\)
-
K공식은 생략.. 아래 함수에 구현되어 있으므로 참고
# 초기값 : x'(t) = x, x(0) = 1, x(t) = e^t
import matplotlib.pyplot as plt
import numpy as np
def f(t, x): # x' -> x'(t) 구하는 함수
return x # 초기값 보면 x
def RK4(a,b,x,n): # x는 x(0)
h = (b-a)/n
t = a
answerT = [t]
answerX = [x] # 여기까진 오일러랑 동일
for k in range(0,n):
k1 = h*f(t,x)
k2 = h*f(t+0.5*h, x+0.5*k1)
k3 = h*f(t+0.5*h, x+0.5*k2)
k4 = h*f(t+h, x+k3)
x = x+(k1+2.0*k2+2.0*k3+k4)/6.0
t = t+h
answerT.append(t)
answerX.append(x)
return answerT, answerX
전부 동시에 비교
# 전부 동시에 그려보겠음.
# 초기값 : x'(t) = x, x(0) = 1, x(t) = e^t
# n = 10단계로, [0,4] 구간
n = 10
start = 0.0
end = 4.0
bX = []
bY = []
for i in range(0,n+1): # 기존 e^t 함수 그래프를 보여주기 위함
x = start + (end-start)/n*i
y = np.exp(x)
bX.append(x)
bY.append(y)
aT, aX = Euler(start, end, 1, n)
rT, rX = RK4(start, end, 1, n) # 이것만 추가
plt.plot(aT,aX, 'ro-', label='Euler\'s method')
plt.plot(rT,rX, 'yo-', label='RK4')
plt.plot(bX,bY,'bo',label='y=exp(x)') # 구분 위해 점만 찍음
plt.legend()
plt.show()
댓글남기기