Loading [MathJax]/jax/output/HTML-CSS/jax.js

2020년 12월 16일 수요일

Numeric Analysis 3 - ODE

Numeric Analysis 3 - ODE

Numeric Analysis 3 - ODE

In [1]:
from math import *
import matplotlib.pyplot as plt
%matplotlib inline 

First-Order ODEs

Initial value problem

y=f(x,y),y(x0)=y0

at the equidistant points on the x-axis

x1=x0+h,x2=x0+2h,x3=x0+3h,

where the step size h is a fixed number, for instance, 0.2 or 0.1 or 0.01

We compute approximate numeric values of y(x)

y1,y2,y3,

By the Taylor series

y(x+h)=y(x)+hy(x)+h22y(x)+

For small h the higher powers h2,h3, are very small.

y(x+h)y(x)+hy(x)=y(x)+hf(x,y)

The Euler method is

yn+1=yn+hf(xn,yn)(n=0,1,)

[ Example ] Obtain numerical solution with h=0.2

y=y+x,y(0)=0

The exact solution is y=exx1


In [2]:
from math import *

def f(x,y):   # y'
    return y + x

h = 0.2
N = 6
x = [0]*N
y = [0]*N   # initial value y[0] = 0

# print(x,y)

for n in range(N-1):     # n = 0, 1, 2, ... 4
    x[n] = n*h
    x[n+1] = (n+1)*h
    y[n+1] = y[n] + h * f( x[n], y[n] )


print(x,y)

yEuler = y     # 나중에 비교를 위해서 보관
[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0] [0, 0.0, 0.04000000000000001, 0.12800000000000003, 0.27360000000000007, 0.4883200000000001]

Improved Euler Method. Predictor, Corrector

The predictor is calculated by

yn+1=yn+hf(xn,yn)

The corrector is then calculated by

yn+1=yn+12h[f(xn,yn)+f(xn+1,yn+1)]

[ Example ] Obtain numerical solution with h=0.2

y=y+x,y(0)=0

The exact solution is y=exx1

In [3]:
from math import *

def f(x,y):   # y'
    return y + x

h = 0.2
N = 6
x = [0]*N
y = [0]*N   # initial value y[0] = 0
ypre = [0]*N

for n in range(N-1):
    x[n] = n*h
    ypre[n+1] = y[n] + h * f( x[n], y[n] )  # predictor
    x[n+1] = (n+1)*h
    y[n+1] = y[n] + h/2 *( f(x[n],y[n]) + f(x[n+1],ypre[n+1]) ) # corrector

    
# 비교
print('수치해를 정답과 비교 \n')

print('     x       Euler    Improved Euler   Exact')
for n in range(N):
    yexact = exp(x[n]) - x[n] - 1
    print('%9.6f   %9.6f   %9.6f   %9.6f' %( x[n], yEuler[n], y[n], yexact ) )

    
yImEuler = y
수치해를 정답과 비교 

     x       Euler    Improved Euler   Exact
 0.000000    0.000000    0.000000    0.000000
 0.200000    0.000000    0.020000    0.021403
 0.400000    0.040000    0.088400    0.091825
 0.600000    0.128000    0.215848    0.222119
 0.800000    0.273600    0.415335    0.425541
 1.000000    0.488320    0.702708    0.718282

Runge–Kutta Method

image.png

In [4]:
# Runge-Kutta method

from math import *

def f(x,y):   # y'
    return y + x

h = 0.2
N = 6
x = [0]*N
y = [0]*N   # initial value y[0] = 0

for n in range(N-1):
    x[n] = n*h
    k1 = h* f( x[n], y[n] )
    k2 = h* f( x[n]+h/2, y[n]+k1/2 )
    k3 = h* f( x[n]+h/2, y[n]+k2/2 )
    k4 = h* f( x[n]+h, y[n]+k3 )
    x[n+1] = (n+1)*h
    y[n+1] = y[n] + 1/6 *( k1 + 2*k2 + 2*k3 + k4 )

    
# 비교
print('수치해를 정답과 비교 \n')

print('     x   Improved Euler  Runge-Kutta   Exact')
for n in range(N):
    yexact = exp(x[n]) - x[n] - 1
    print('%9.6f   %9.6f   %9.6f   %9.6f' %( x[n], yImEuler[n], y[n], yexact ) )
수치해를 정답과 비교 

     x   Improved Euler  Runge-Kutta   Exact
 0.000000    0.000000    0.000000    0.000000
 0.200000    0.020000    0.021400    0.021403
 0.400000    0.088400    0.091818    0.091825
 0.600000    0.215848    0.222106    0.222119
 0.800000    0.415335    0.425521    0.425541
 1.000000    0.702708    0.718251    0.718282

Methods for Systems and Higher Order ODEs

Initial value problems for first-order systems of ODEs

y1=f1(x,y1,y2,,ym),y1(x0)=y10y2=f2(x,y1,y2,,ym),y2(x0)=y20ym=fm(x,y1,y2,,ym),ym(x0)=ym0

Initial value problem for an m th-order ODE

y(m)=f(x,y,y,y,,y(m1))

with initial conditions y(x0)=K1,y(x0)=K2,,y(m1)(x0)=Km

The higher-order ODE can be rewritten as a system of the first-order ODEs by setting

y1=y,y2=y,y3=y,,ym=y(m1)

Then we obtain the system of first-order ODEs

y1=y2 y2=y3 ym1=ym ym=f(x,y1,y2,y3,,ym)

with initial conditions y1(x0)=K1,y2(x0)=K2,,ym(x0)=Km

Euler Method for Systems

This method will not be accurate enough for practical purposes.

For first-order systems of ODEs, the Euler method prescribes

yn+1=yn+hf(xn,yn)

in components y1,n+1=y1,n+hf1(x,y1,n,y2,n,,ym,n), y2,n+1=y2,n+hf2(x,y1,n,y2,n,,ym,n), ym,n+1=ym,n+hfm(x,y1,n,y2,n,,ym,n),

[Example] Second-Order ODE. Mass–Spring System

y+2y+0.75y=0,y(0)=3,y(0)=2.5

Obtain the numerical solution with step h=0.2

(exact solution) y=2e0.5x+e1.5x


We let y1=y,y2=y

The the second-order ODE becomes

y1=y2,y1(0)=3y2=2y20.75y1,y2(0)=2.5
In [5]:
# Euler method

from math import *

def f1(x,y1,y2):            # y1' = f1(x,y1,y2)
    return y2

def f2(x,y1,y2):            # y2' = f2(x,y1,y2)
    return -2*y2 - 0.75*y1

h = 0.2
N = 6
x =  [0]*N
y1 = [0]*N   
y2 = [0]*N

# initial value 
y1[0] = 3
y2[0] = -2.5

for n in range(N-1):     # n = 0,1,2, ... 4
    x[n] = n*h
    x[n+1] = (n+1)*h
    y1[n+1] = y1[n] + h* f1( x[n], y1[n], y2[n] )
    y2[n+1] = y2[n] + h* f2( x[n], y1[n], y2[n] )

   
# 비교
print('수치해를 정답과 비교 \n')
print('     x       Euler       Exact')

for n in range(N):
    yexact = 2*exp(-0.5*x[n]) + exp(-1.5*x[n])
    print('%9.6f   %9.6f   %9.6f' %( x[n], y1[n], yexact ) )


yEuler = y1  # 나중을 위해 저장
수치해를 정답과 비교 

     x       Euler       Exact
 0.000000    3.000000    3.000000
 0.200000    2.500000    2.550493
 0.400000    2.110000    2.186273
 0.600000    1.801000    1.888206
 0.800000    1.552300    1.641834
 1.000000    1.349050    1.436191

Runge–Kutta Methods for Systems

At each step n, four auxiliary quantities are calculated

k1=hf(xn,yn)k2=hf(xn+12h,yn+12k1)k3=hf(xn+12h,yn+12k2)k4=hf(xn+h,yn+k3)

New values at the next step n+1 are calculated by

yn+1=yn+16(k1+2k2+2k3+k4)

[Example] Second-Order ODE. Mass–Spring System

y+2y+0.75y=0,y(0)=3,y(0)=2.5

Obtain the numerical solution with step h=0.2

(exact solution) y=2e0.5x+e1.5x


In [6]:
# Runge-Kutta method

from math import *

def f1(x,y1,y2):            # y1' = f1(x,y1,y2)
    return y2

def f2(x,y1,y2):            # y2' = f2(x,y1,y2)
    return -2*y2 - 0.75*y1

h = 0.2
N = 6
x =  [0]*N
y1 = [0]*N   
y2 = [0]*N

# initial value 
y1[0] = 3
y2[0] = -2.5

for n in range(N-1):     # n = 0,1,2, ... 4
    x[n] = n*h
    x[n+1] = (n+1)*h

    k11 = h* f1( x[n], y1[n], y2[n] )
    k12 = h* f2( x[n], y1[n], y2[n] )
    
    k21 = h* f1( x[n]+h/2, y1[n]+k11/2, y2[n]+k12/2 )
    k22 = h* f2( x[n]+h/2, y1[n]+k11/2, y2[n]+k12/2 )
    
    k31 = h* f1( x[n]+h/2, y1[n]+k21/2, y2[n]+k22/2 )
    k32 = h* f2( x[n]+h/2, y1[n]+k21/2, y2[n]+k22/2 )
    
    k41 = h* f1( x[n]+h, y1[n]+k31, y2[n]+k32 )
    k42 = h* f2( x[n]+h, y1[n]+k31, y2[n]+k32 )
    
    y1[n+1] = y1[n] + 1/6 *( k11 + 2*k21 + 2*k31 + k41 )
    y2[n+1] = y2[n] + 1/6 *( k12 + 2*k22 + 2*k32 + k42 )
    
    
# 비교
print('수치해를 정답과 비교 \n')
print('     x        Euler     Runge-Kutta   Exact')

for n in range(N):
    yexact = 2*exp(-0.5*x[n]) + exp(-1.5*x[n])
    print('%9.6f   %9.6f   %9.6f   %9.6f' %( x[n], yEuler[n], y1[n], yexact ) )
수치해를 정답과 비교 

     x        Euler     Runge-Kutta   Exact
 0.000000    3.000000    3.000000    3.000000
 0.200000    2.500000    2.550512    2.550493
 0.400000    2.110000    2.186302    2.186273
 0.600000    1.801000    1.888238    1.888206
 0.800000    1.552300    1.641866    1.641834
 1.000000    1.349050    1.436221    1.436191

댓글 없음:

댓글 쓰기

Numeric Analysis 4 - Numeric Linear Algebra

Numeric Analysis 4 - Numeric Linear Algebra Numeric Linear Algebra ¶ ...