sample\algorithms\09_numeric.hsp » Plain Format
;============================================================
; アルゴリズム 44〜47: 数値計算
; 44. Newton 法 (非線形方程式の根)
; 45. Simpson 積分 (1/3 則)
; 46. Runge-Kutta 4 次 (常微分方程式)
; 47. Gauss-Jordan 消去法 (連立 1 次方程式)
;============================================================
#include "hsp3cl_net_64.as"
#module
; ----- 44. Newton 法 (f(x) = x^2 - 2 の根) -----
#defcfunc newton_sqrt double _target, double _x0, int _max_iter, \
local x, local i
x = _x0
for i, 0, _max_iter
; f(x) = x^2 - target
; f'(x) = 2x
; x <- x - f/f'
x = x - (x * x - _target) / (2.0 * x)
next
return x
; ----- 45. Simpson 積分 (a..b, n 分割、n は偶数) -----
; f(x) = x^2 の場合をハードコード (関数値を差し替え可)
#defcfunc simpson_square double _a, double _b, int _n, \
local h, local s, local i, local x
h = (_b - _a) / _n
s = _a * _a + _b * _b
for i, 1, _n
x = _a + h * i
if i & 1 : s += 4.0 * x * x : else : s += 2.0 * x * x
next
return s * h / 3.0
; ----- 46. RK4 (y' = f(t, y), y(t0) = y0) -----
; デモ: y' = -2y (解析解 y(t) = y0 * exp(-2t))
#defcfunc rk4_decay double _t0, double _y0, double _t1, int _steps, \
local t, local y, local h, local k1, local k2, local k3, local k4, local i
h = (_t1 - _t0) / _steps
t = _t0 : y = _y0
for i, 0, _steps
k1 = -2.0 * y
k2 = -2.0 * (y + h * k1 / 2.0)
k3 = -2.0 * (y + h * k2 / 2.0)
k4 = -2.0 * (y + h * k3)
y += h * (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0
t += h
next
return y
; ----- 47. Gauss-Jordan 消去法 (N x N 連立) -----
; 拡大係数行列 A|b を in/out、解 x は A の最右列
#deffunc gauss_jordan array _m, int _n, \
local i, local j, local k, local pivot, local r, local maxv, local maxr, local tmp
; 行数 n、列数 n+1 (augmented)
for i, 0, _n
; ピボット選択 (部分ピボット)
maxv = absf(_m(i * (_n + 1) + i))
maxr = i
for r, i + 1, _n
if absf(_m(r * (_n + 1) + i)) > maxv {
maxv = absf(_m(r * (_n + 1) + i))
maxr = r
}
next
if maxr != i {
for k, 0, _n + 1
tmp = _m(i * (_n + 1) + k)
_m(i * (_n + 1) + k) = _m(maxr * (_n + 1) + k)
_m(maxr * (_n + 1) + k) = tmp
next
}
pivot = _m(i * (_n + 1) + i)
if absf(pivot) < 1e-12 {
mes " (singular matrix)"
return -1
}
for k, 0, _n + 1
_m(i * (_n + 1) + k) = _m(i * (_n + 1) + k) / pivot
next
for j, 0, _n
if j != i {
pivot = _m(j * (_n + 1) + i)
for k, 0, _n + 1
_m(j * (_n + 1) + k) = _m(j * (_n + 1) + k) - pivot * _m(i * (_n + 1) + k)
next
}
next
next
return 0
#global
; ===== デモ =====
mes "=== Newton 法: sqrt(2) ==="
mes strf("x = %.10f (期待: 1.41421356...)", newton_sqrt(2.0, 1.0, 10))
mes ""
mes "=== Simpson 積分 ∫₀² x² dx = 8/3 ==="
mes strf("n=10: %.10f", simpson_square(0.0, 2.0, 10))
mes strf("n=100: %.10f", simpson_square(0.0, 2.0, 100))
mes strf("期待: %.10f", 8.0 / 3.0)
mes ""
mes "=== RK4: y'=-2y, y(0)=1, t=1 ==="
mes strf("RK4 (50 steps): y(1) = %.10f", rk4_decay(0.0, 1.0, 1.0, 50))
mes strf("解析解: y(1) = %.10f = e^(-2)", 0.1353352832366127)
mes ""
mes "=== Gauss-Jordan: 3x + 2y - z = 1, 2x - 2y + 4z = -2, -x + y/2 - z = 0 ==="
; A|b (3x4):
ddim mt, 12
mt(0) = 3.0 : mt(1) = 2.0 : mt(2) = -1.0 : mt(3) = 1.0
mt(4) = 2.0 : mt(5) = -2.0 : mt(6) = 4.0 : mt(7) = -2.0
mt(8) = -1.0 : mt(9) = 0.5 : mt(10)= -1.0 : mt(11)= 0.0
gauss_jordan mt, 3
mes strf("x = %.6f (期待: 1)", mt(3))
mes strf("y = %.6f (期待: -2)", mt(7))
mes strf("z = %.6f (期待: -2)", mt(11))
end 0