ルンゲクッタ法(四次)を実装(JavaScript)


ルンゲクッタ法とは

ルンゲクッタ法は、常微分方程式において、解析的に解を求められない状況で初期値を元に適切な答えを求めるための数値解析手法.

$$\frac{dy}{dx} = f(y,x)$$

上記常微分方程式と適切な初期値が与えられる時にその解を数値計算で求めます.
今回は4次のルンゲクッタのJavaScript実装を行います.

参考文献に記載させていただいた神戸大学の陰山様の資料やYouTubeがイメージを掴むのによいかと思います.
次数に関しては、これも参考文献のシキノート様のが非常に参考になるかと思います.

ルンゲクッタ実装

想定する関数は下記とします.

$$y = \frac{1}{10} cos(x) + 3.9$$

常微分方程式は以下とします.

$$\frac{dy}{dx} = f(x) = -\frac{1}{10} sin(x)$$

y不使用のため、diffEquationでは、xしか引数に取っていません.
初期値は$(x,y)=(0, 4)$.

rungeFに推定した関数の結果が入ります.

const COEFF = 0.1;
const DATA_NUM = 100;
const HALF_DATA_NUM = Math.floor(DATA_NUM/2);
const RUNGE_STEP = 0.1;
let init_x = 0;
let init_y = 4;
let X = [];
let datas = [];

for(let i = 0; i < DATA_NUM; i++){
    X.push((i - HALF_DATA_NUM) * COEFF);
}

function ansEquation(x){
    return 1/10 * Math.cos(x) + 3.9;
}

function diffEquation(x){
    return -1/10 * Math.sin(x);
}

let ansY = X.map((x)=> ansEquation(x));
let ansF = X.map(function(x,index){return {x:x, y:ansY[index]}});
let maxX = Math.max(...X);
let curX = init_x;
let prevY = init_y;
let rungeF = [{x:curX, y:init_y}];

while(maxX > curX){
    let k1 = diffEquation(curX);
    let k2 = diffEquation(curX + RUNGE_STEP / 2 * k1);
    let k3 = diffEquation(curX + RUNGE_STEP / 2 * k2);
    let k4 = diffEquation(curX + RUNGE_STEP     * k3);
    let y = prevY + RUNGE_STEP * (
        k1 * 1/6 + k2 * 2/6 + k3 * 2/6 + k4 * 1/6
    );

    curX += RUNGE_STEP;

    rungeF.push({x:curX, y:y});

    prevY = y;
}

参考文献