๐Ÿ”– Automatic Differentiation Series

  1. ๐Ÿ’ป Numerical Differentiation
  2. ๐Ÿ–Š๏ธ Symbolic Differentiation
  3. ๐Ÿค– Automatic Differentiation

๐Ÿ“‰ ์ˆ˜์น˜์  ๋ฏธ๋ถ„์˜ ํ•œ๊ณ„

์ €๋ฒˆ ํฌ์ŠคํŠธ์—์„œ ์ˆ˜์น˜์  ๋ฏธ๋ถ„์„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ๋‹ค๋ค„๋ณด์•˜๋Š”๋ฐ, ์–ด๋– ์…จ๋‚˜์š”? ์•„๋งˆ, ์ฝ”๋”ฉ์— ๋Œ€ํ•œ ์กฐ๊ธˆ์˜ ์ง€์‹๋งŒ ์žˆ์œผ๋ฉด ์˜คํžˆ๋ ค ๊ณ ๋“ฑํ•™๊ต๋•Œ์˜ ๋ฏธ๋ถ„๋ณด๋‹ค ํ›จ์”ฌ ์‰ฝ๊ฒŒ ๋Š๊ปด์ง€์…จ์„ ๊ฒ๋‹ˆ๋‹ค. ์ €ํฌ๊ฐ€ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด๋ผ๊ณ ๋Š” ๊ทธ์ € ๋„ํ•จ์ˆ˜์˜ ์ •์˜์— ๋”ฐ๋ผ ํ•จ์ˆ˜์— ๊ฐ ๊ตฌ๊ฐ„ ๊ฐ’์„ ๋Œ€์ž…ํ•œ ๊ฒƒ์ด ์ „๋ถ€์˜€๋Š”๋ฐ, ์ด๋ฅผ ์ฝ”๋“œ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ๊ฒฐ๊ตญ ๋‹ค์Œ์˜ ์ฝ”๋“œ์— ์ง€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

# Python
def differentiation(f, x, h=1e-06):
  return (f(x + h) - f(x)) / h

๋‚˜๋จธ์ง€๋Š” ์ด๋ฅผ ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜, ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ฑฐ๋‚˜ ์ œ๋„ˆ๋ฆญ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๋„์ž…ํ•˜๋Š” ๋“ฑ์˜ ๊ตฌํ˜„๋ฐฉ๋ฒ•์˜ ์ฐจ์ด์ผ ๋ฟ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ˆ˜์น˜์  ๋ฏธ๋ถ„ ๋ฐฉ๋ฒ•์€ ๊ต‰์žฅํžˆ ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„๊ณผ ์—„์ฒญ ๋น ๋ฅธ ๊ณ„์‚ฐ์†๋„๋ฅผ ๊ฐ€์ ธ์„œ ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ๋ฏธ๋ถ„์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค๋งŒ, ์˜ค์ฐจ๊ฐ€ ํ•„์—ฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š” ๋‹จ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์˜ค์ฐจ์— ํฌ๊ฒŒ ๋ฏผ๊ฐํ•˜์ง€ ์•Š์€ ๋ฌธ์ œ๋‚˜, Step ์ˆ˜๊ฐ€ ์ ์–ด์„œ ์˜ค์ฐจ๊ฐ€ ํฌ๊ฒŒ ์Œ“์ด์ง€ ์•Š๋Š” ๋ฏธ๋ถ„๋ฐฉ์ •์‹์„ ํ‘ธ๋Š” ๊ฒฝ์šฐ์—” ์ถฉ๋ถ„ํ•˜์ง€๋งŒ, ์˜ค์ฐจ์— ๋ฏผ๊ฐํ•˜๊ฑฐ๋‚˜ Step ์ˆ˜๊ฐ€ ๋งŽ์•„์„œ ์˜ค์ฐจ๊ฐ€ ์Œ“์—ฌ ์œ ์˜๋ฏธํ•œ ์ฐจ์ด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ฏธ๋ถ„๋ฐฉ์ •์‹์˜ ๊ฒฝ์šฐ์—” ํฐ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ๋กœ “๋กœ๋ Œ์ฆˆ์˜ ๋‚˜๋น„"๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿฆ‹ ๋กœ๋ Œ์ฆˆ์˜ ๋‚˜๋น„

Lorenz Butterfly

์—๋“œ์›Œ๋“œ ๋กœ๋ Œ์ฆˆ๋Š” ๊ฑธ์ถœํ•œ ์ˆ˜ํ•™์ž๋กœ, ํŠนํžˆ ์นด์˜ค์Šค ์ด๋ก ์˜ ์„ ๊ตฌ์ž๋กœ ์œ ๋ช…ํ•˜์‹  ๋ถ„์ž…๋‹ˆ๋‹ค. ๊ทธ๋Š” 1963๋…„์— ๋Œ€๊ธฐ ๋Œ€๋ฅ˜์˜ ๊ฐ„๋‹จํ•œ ์ˆ˜ํ•™์  ๋ชจํ˜•์„ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ, ์ด ๋ชจ๋ธ์€ ๋‹ค์Œ์˜ 3๊ฐœ์˜ ์ƒ๋ฏธ๋ถ„๋ฐฉ์ •์‹์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

$$ \begin{align} \frac{dx}{dt} &= \sigma(y-x) \\ \frac{dy}{dt} &= x (\rho - z) - y \\ \frac{dz}{dt} &= xy - \beta z \end{align} $$

๋ถ„๋ช… ์•„์ฃผ ๊ฐ„๋‹จํ•œ ๋ฏธ๋ถ„๋ฐฉ์ •์‹์ธ๋ฐ, ๋†€๋ž๊ฒŒ๋„ ์•„์ฃผ ๋ณต์žกํ•œ ํ˜•ํƒœ์˜ ํ•ด๊ฐ€ ๋„์ถœ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ์˜ ๋Œ€ํ‘œ์ ์ธ ํ•ด์˜ ํ˜•ํƒœ๊ฐ€ ์œ„์—์„œ ์ฒจ๋ถ€ํ•œ ๊ทธ๋ฆผ์ž…๋‹ˆ๋‹ค. ์ด ์‹œ์Šคํ…œ์€ ๊ต‰์žฅํžˆ ์˜ˆ๋ฏผํ•œ๋ฐ, ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ์กฐ๊ธˆ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ํ˜น์€ Step size๋ฅผ ์กฐ๊ธˆ๋งŒ ๋ฐ”๊ฟ”๋„ ํ•ด์˜ ํ˜•ํƒœ๋Š” ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ํ˜•ํƒœ๋กœ, ๊ทธ๊ฒƒ๋„ ๊ต‰์žฅํžˆ ํŒŒ๊ฒฉ์ ์œผ๋กœ ๋ณ€ํ˜•๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์œ„์˜ ๊ทธ๋ฆผ์€ ์˜ค์ผ๋Ÿฌ(Euler) ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ์ˆ˜์น˜์  ๋ฏธ๋ถ„๋ฐฉ์ •์‹ ํ•ด๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ ํ’€์—ˆ๋Š”๋ฐ, ์œ„์™€ ๋ชจ๋“  ์กฐ๊ฑด์„ ๋™์ผํ•˜๊ฒŒ ๋†“๊ณ  ๋ฐฉ๋ฒ•๋งŒ ๋ฃฝ๊ฒŒ-์ฟ ํƒ€(Runge-Kutta 4th order) ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ”๊พธ๋ฉด ๋‹ค์Œ์˜ ๊ทธ๋ฆผ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

Lorenz Butterfly (RK4)

์˜ค๋กœ์ง€ ๋ฐฉ๋ฒ•๋งŒ ๋ฐ”๊พธ์—ˆ์„ ๋ฟ์ธ๋ฐ ๊ฒฐ๊ณผ๊ฐ€ ์ƒ๋‹นํžˆ ๋งŽ์ด ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด ๊ฒฝ์šฐ์—๋Š” ์ „์ฒด์ ์ธ ํ˜•ํƒœ๋Š” ๋ฐ”๋€Œ์ง€ ์•Š์ง€๋งŒ, ํŠน์ • ๋งค๊ฐœ๋ณ€์ˆ˜ ์ฃผ๋ณ€์—์„œ๋Š” ์•„์˜ˆ ํ˜•ํƒœ ์ „์ฒด๊ฐ€ ๊ธ‰๊ฒฉํ•˜๊ฒŒ ๋ณ€ํ˜•๋˜๋Š” ๊ฒฝ์šฐ๋„ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์—๋Š” ์˜ค์ฐจ๊ฐ€ ํ•„์—ฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์ˆ˜์น˜์  ๋ฏธ๋ถ„ ๋ฐฉ๋ฒ•์ด ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ํ’€์–ด์•ผ ํ• ๊นŒ์š”?


๐Ÿ‡ฌ๐Ÿ‡ท ๊ธฐํ˜ธ์  ๋ฏธ๋ถ„ (Symbolic Differentiation)

์ธ๊ฐ„์€ ์ ์ ˆํ•œ ๊ต์œก๋งŒ ๋ฐ›๋Š”๋‹ค๋ฉด ๋ฏธ๋ถ„์„ ์•„๋ฌด๋Ÿฐ ์˜ค์ฐจ์—†์ด ๊ณ„์‚ฐํ•ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๋ฌผ๋ก , ๊ณ„์‚ฐ์‹ค์ˆ˜๋กœ ์ธํ•œ ์˜ค์ฐจ๋Š” ์ข…์ข… ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.) ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ํ•จ์ˆ˜์˜ ๋„ํ•จ์ˆ˜๋ฅผ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค.

$$ y = x^2 $$

์ด์ „ ๊ธ€์—์„œ ๋‹ค๋ฃจ์—ˆ๋‹ค์‹œํ”ผ ์ˆ˜์น˜์  ๋ฏธ๋ถ„ ๊ตฌํ˜„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๋˜‘๊ฐ™์œผ๋ฉด ์‹ฌ์‹ฌํ•˜๋‹ˆ ์š”์ฆ˜ ๊ฐ๊ด‘๋ฐ›๋Š” ์ˆ˜์น˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ธ Julia๋กœ ํ‘œํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

# Julia
function df(x, f, h=1e-06)
  return (f(x+h) - f(x)) / h
end

# Derivative
dx2(x) = df(x, x -> x^2)

# Print
println(dx2(1)) # 2.0000009999243673

์ด๋ฒˆ์—” ๊ณ ๋“ฑํ•™์ƒ์ด ํ‘ธ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ด…์‹œ๋‹ค. (๋Œ€ํ•œ๋ฏผ๊ตญ ๊ณ ๋“ฑํ•™๊ต 2ํ•™๋…„ ์ˆ˜ํ•™2 ๊ณผ์ •์„ ์ด์ˆ˜ํ•œ ํ•™์ƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.)

$$ \begin{align} \frac{d}{dx}(x^2) &= \lim_{h \rightarrow 0} \frac{(x+h)^2 - x^2}{h} \\ &= \lim_{h\rightarrow 0} \frac{2hx + h^2}{h} \\ &= 2x \end{align} $$

์—ฌ๊ธฐ์— 1์„ ๋Œ€์ž…ํ•˜๋ฉด ์ •ํ™•ํžˆ 2๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค. ์œ„์—์„œ ์ˆ˜์น˜์  ๋ฏธ๋ถ„์˜ ๊ฒฐ๊ณผ์™€ ๋‹ฌ๋ฆฌ ์˜ค์ฐจ๋Š” ํฌํ•จ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ฏธ๋ถ„์„ ๋ฐฐ์šด ์‚ฌ๋žŒ์ผ ๊ฒฝ์šฐ, ์œ„ ํ’€์ด๋Š” ์ „ํ˜€ ์–ด๋ ค์šด ํ’€์ด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ทœ์น™๋งŒ ์ž˜ ์ง€ํ‚จ๋‹ค๋ฉด ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค์„ ๋ฏธ๋ถ„ํ•  ๋•Œ์—๋„ ํฐ ์–ด๋ ค์›€์€ ์—†์„ ๊ฒ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ๊ทœ์น™์ด ์กฐ๊ธˆ ๋งŽ๊ธด ํ•ฉ๋‹ˆ๋‹ค ใ…Žใ…Ž..

๋ฌผ๋ก  ๊ทœ์น™์ด ์กฐ๊ธˆ ๋งŽ๊ธด ํ•ฉ๋‹ˆ๋‹ค ใ…Žใ…Ž..

๊ทธ๋ ‡๋‹ค๋ฉด ์ปดํ“จํ„ฐ์—๊ฒŒ ๊ทœ์น™์„ ๊ฐ€๋ฅด์น˜๋ฉด ์–ด๋–จ๊นŒ์š”? ์–ด๋–ป๊ฒŒ ๊ฐ€๋ฅด์น˜๋ƒ๊ฐ€ ๊ด€๊ฑด์ด๊ฒ ์ง€๋งŒ ์ผ๋‹จ ๊ฐ€๋ฅด์น  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์˜ค์ฐจ์—†๋Š” ์™„๋ฒฝํ•œ ๋ฏธ๋ถ„์„ ์ปดํ“จํ„ฐ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ ์‚ฌ๋žŒ๋“ค์€ ์ด๋ฏธ ๊ทธ๊ฒƒ์„ ๊ตฌํ˜„ํ•˜์˜€๊ณ  ์ด๋ฅผ CAS(Computer Algebra System)๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์ธ CAS๋กœ๋Š” Mathematica, Matlab, Maple ๋“ฑ์˜ ์ƒ์—…์šฉ ํ”„๋กœ๊ทธ๋žจ๋“ค๊ณผ Python์œผ๋กœ ๊ตฌํ˜„๋œ Sympy, Sagemath ๋“ฑ์˜ ๋ฌด๋ฃŒ ํ”„๋กœ๊ทธ๋žจ ํ˜น์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. CAS๋Š” ์‹ค์ œ๋กœ ์ธ๊ฐ„์ด ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฏธ๋ถ„, ์ ๋ถ„, ๋Œ€์ˆ˜ ๋ฟ ์•„๋‹ˆ๋ผ ์‹ฌ์ง€์–ด ๋ฏธ๋ถ„๊ธฐํ•˜ ๋“ฑ์˜ ๊ณ ๊ธ‰ ์ˆ˜ํ•™ ๋ฌธ์ œ๊นŒ์ง€๋„ ํ’€์–ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌด๋ ค ์ด๋ฆ„๋„ SageManifolds ์ž…๋‹ˆ๋‹ค.

๋ฌด๋ ค ์ด๋ฆ„๋„ SageManifolds ์ž…๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” sagemath๋ฅผ ์ด์šฉํ•œ ๊ฐ„๋‹จํ•œ ๋„ํ•จ์ˆ˜ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

var('x')        # ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
f(x) = x^2      # ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
df = diff(f, x) # ๋„ํ•จ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
print(df(1))    # 2

์ •ํ™•ํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐ„๋‹จํ•˜๊ธฐ๊นŒ์ง€ ํ•˜๋‹ˆ ๋” ์ด์ƒ ์ˆ˜์น˜์  ๋ฏธ๋ถ„์„ ๊ณ ์ง‘ํ•  ์ด์œ ๋Š” ์—†์–ด๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ์—„์ฒญ๋‚œ CAS์—๋„ ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์†๋„์ž…๋‹ˆ๋‹ค. ๊ธฐํ˜ธ์  ๋ฏธ๋ถ„ ์ž์ฒด๋Š” ๊ณ„์‚ฐ ์†๋„๊ฐ€ ๋น ๋ฅผ ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๊ฒƒ์— ์ˆ˜์น˜ ๊ฐ’๋“ค์„ ๋Œ€์ž…ํ•  ๋•Œ ํ˜„์ €ํ•˜๊ฒŒ ์†๋„ ์ €ํ•˜๊ฐ€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๊ฐ„๋‹จํ•œ ๋ฏธ๋ถ„ ๊ณ„์‚ฐ์— ํฌ๊ธฐ๊ฐ€ ํฐ ๋ฐฐ์—ด ๊ฐ’์„ ๋Œ€์ž…ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ์ธก์ •ํ•œ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. Peroxide๋Š” Rust์˜ ์ˆ˜์น˜๊ณ„์‚ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋ฆ„์ด๋ฉฐ ํ›„์— ๋‹ค๋ฃฐ ์ž๋™๋ฏธ๋ถ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜์—ฌ ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜์˜€๊ณ , numpy๋Š” Python์˜ ์œ ๋ช…ํ•œ ์ˆ˜์น˜๊ณ„์‚ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ˆ˜์น˜์  ๋ฏธ๋ถ„์œผ๋กœ ๊ณ„์‚ฐํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ Sagemath๋Š” ๊ธฐํ˜ธ์  ๋ฏธ๋ถ„์œผ๋กœ ๊ณ„์‚ฐ ํ›„ ์ˆ˜์น˜ ๊ฐ’์„ ๋Œ€์ž…ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค.

Linear scale ๊ทธ๋ž˜ํ”„์ž…๋‹ˆ๋‹ค.

Linear scale ๊ทธ๋ž˜ํ”„์ž…๋‹ˆ๋‹ค.

Log scale ๊ทธ๋ž˜ํ”„์ž…๋‹ˆ๋‹ค.

Log scale ๊ทธ๋ž˜ํ”„์ž…๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์–ด๋–ค ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ–ˆ๋Š”์ง€์— ๋”ฐ๋ผ ์‹ค์ œ ์ˆ˜์น˜ ๊ณ„์‚ฐ์—์„œ์˜ ๊ฒฐ๊ณผ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ Julia ์–ธ์–ด ํŒ€์—์„œ ์‹ค์‹œํ•œ Benchmark ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

Log scale์ž„์„ ์ฐธ๊ณ ํ•˜์—ฌ ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. (์ถœ์ฒ˜: https://julialang.org/benchmarks/)

Log scale์ž„์„ ์ฐธ๊ณ ํ•˜์—ฌ ๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. (์ถœ์ฒ˜: https://julialang.org/benchmarks/)

๊ทธ๋ฆผ์„ ๋ณด๋ฉด Matlab์˜ ์˜คํ”ˆ์†Œ์Šค ๊ฒฉ์ธ Octave๋Š” ์˜ˆ์™ธ๋กœ ์น˜๋”๋ผ๋„ Mathematica๊ฐ€ ์ƒ๊ฐ๋ณด๋‹จ ๋Š๋ฆฌ์ง€ ์•Š์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๊ทธ๋ž˜๋„ C๋ณด๋‹ค ๊ฑฐ์˜ 10~100๋ฐฐ ๋Š๋ฆฌ๊ธด ํ•˜์ง€๋งŒ์š”.) Mathematica๋„ ํ–‰๋ ฌ ๊ณ„์‚ฐ์€ BLAS๋ฅผ ์ด์šฉํ•˜๊ณ  ๊ฐ–๊ฐ€์ง€ ํƒ์›”ํ•œ ์ˆ˜์น˜ ๊ณ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ธฐ์— ํŠน์ • ๊ณ„์‚ฐ๋“ค์€ ์‹ฌ์ง€์–ด numpy๋ฅผ ์ด์šฉํ•œ Python๋ณด๋‹ค ๋น ๋ฅด๊ธฐ๊นŒ์ง€ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ, Mathematica์—์„œ๋„ ๊ธฐํ˜ธ์  ๋ฏธ๋ถ„๊ณผ ์ˆ˜์น˜์ ์ธ ์—ฐ์‚ฐ์„ ์„œ๋กœ ์˜ค๊ฐˆ๋•Œ์—๋Š” ์—ญ์‹œ๋‚˜ ํฐ ์†๋„์ €ํ•˜๊ฐ€ ํ•„์—ฐ์ ์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๊ทœ๋ชจ๊ฐ€ ํฐ ๋ฏธ๋ถ„ ๊ณ„์‚ฐ์— ๋Œ€ํ•ด์„œ๋Š” ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ•ด์•ผํ• ๊นŒ์š”? ์†๋„ ์ €ํ•˜๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์ˆ˜์น˜์  ๋ฏธ๋ถ„์œผ๋กœ ๊ตฌํ˜„ํ•˜์ž๋‹ˆ ๊ทœ๋ชจ๊ฐ€ ์ปค์„œ ์˜ค์ฐจ๋„ ๊ทธ๋งŒํผ ๋งŽ์ด ์Œ“์ผํ…Œ๊ณ , ์ •ํ™•๋„๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๊ธฐํ˜ธ์  ๋ฏธ๋ถ„์„ ๊ณ ๋ คํ•˜์ž๋‹ˆ ๊ต‰์žฅํžˆ ์˜ค๋žœ ์‹œ์ผ์ด ๊ฑธ๋ฆด ๊ฒƒ์€ ๋ป”ํ•ฉ๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ๋กœ ๊ฒŒ์‚ฐ ๋„์ค‘์— ๋‹ค์šด๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹คํ–‰ํžˆ๋„ ๋ฏธ๋ถ„์— ํ•œํ•ด์„œ๋Š” ๊ฑฐ์˜ ์™„๋ฒฝํ•œ ํ•ด๋‹ต์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค์Œ ํฌ์ŠคํŠธ์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


๐Ÿ”– ๋ถ€๋ก

A. ๋กœ๋ Œ์ฆˆ ๋‚˜๋น„ ์ฝ”๋“œ

์œ„์—์„œ ์ฒจ๋ถ€ํ•œ ๋กœ๋ Œ์ฆˆ ๋‚˜๋น„ ๊ทธ๋ฆผ๋“ค์€ Rust์˜ ์ˆ˜์น˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Peroxide๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ณ„์‚ฐํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์†Œ์Šค์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

extern crate peroxide;
use peroxide::fuga::*;

fn main() -> Result<(), Box<dyn Error>> {
    // =========================================
    //  Declare ODE
    // =========================================
    let mut ex_test = ExplicitODE::new(butterfly);

    let init_state: State<f64> = State::new(
        0.0,
        vec![10.0, 1.0, 1.0],
        vec![0.0, 0.0, 0.0],
    );

    ex_test
        .set_initial_condition(init_state)
        .set_method(ExMethod::Euler)
        .set_step_size(0.01f64)
        .set_times(10000);

    let mut ex_test2 = ex_test.clone();
    ex_test2.set_method(ExMethod::RK4);

    // =========================================
    //  Save results
    // =========================================
    let results = ex_test.integrate();
    let results2 = ex_test2.integrate();

    let mut df_euler = DataFrame::from_matrix(results);
    df_euler.set_header(vec!["t", "x", "y", "z"]);
    df_euler.print();

    let mut df_rk4 = DataFrame::from_matrix(results2);
    df_rk4.set_header(vec!["t", "x", "y", "z"]);
    df_rk4.print();

    df_euler.write_nc("data/euler.nc")?;
    df_rk4.write_nc("data/rk4.nc")?;

    Ok(())
}

fn butterfly(st: &mut State<f64>, _: &NoEnv) {
    let x = &st.value;
    let dx = &mut st.deriv;
    dx[0] = 10f64 * (x[1] - x[0]);
    dx[1] = 28f64 * x[0] - x[1] - x[0] * x[2];
    dx[2] = -8f64/3f64 * x[2] + x[0] * x[1];
}

์ดํ›„์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์€ Python์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

from netCDF4 import Dataset
import matplotlib.pyplot as plt

# Import netCDF file
ncfile1 = './data/euler.nc'
data1 = Dataset(ncfile1)
var1 = data1.variables
ncfile2 = './data/rk4.nc'
data2 = Dataset(ncfile2)
var2 = data2.variables

# Use latex
plt.rc('text', usetex=True)
plt.rc('font', family='serif')

# Prepare Plot
plt.figure(figsize=(10,6), dpi=300)
plt.title(r"Lorenz Butterfly (Euler)", fontsize=16)
plt.xlabel(r'$x$', fontsize=14)
plt.ylabel(r'$z$', fontsize=14)

# Prepare Data to Plot
x1 = var1['x'][:]
z1 = var1['z'][:]  

# Plot with Legends
plt.plot(x1, z1, label=r'Lorenz (Euler)')

# Other options
plt.legend(fontsize=12)
plt.grid()
plt.savefig("euler.png", dpi=300)

# Prepare Plot
plt.figure(figsize=(10,6), dpi=300)
plt.title(r"Lorenz Butterfly (RK4)", fontsize=16)
plt.xlabel(r'$x$', fontsize=14)
plt.ylabel(r'$z$', fontsize=14)

# Prepare Data to Plot
x2 = var2['x'][:]
z2 = var2['z'][:]  

# Plot with Legends
plt.plot(x2, z2, label=r'Lorenz (RK4)')

# Other options
plt.legend(fontsize=12)
plt.grid()
plt.savefig("rk4.png", dpi=300)

์ด์™ธ์— ์ž์„ธํ•œ ์‚ฌํ•ญ์€ Peroxide Gallery์— ๋‚˜์™€์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.