Runge-Kutta method: Difference between revisions

Added Easylang
(Minor formatting changes. Using "strformat". Updated output.)
(Added Easylang)
 
(20 intermediate revisions by 15 users not shown)
Line 28:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">F rk4(f, x0, y0, x1, n)
V vx = [0.0] * (n + 1)
V vy = [0.0] * (n + 1)
Line 50:
V (vx, vy) = rk4(f, 0.0, 1.0, 10.0, 100)
L(x, y) zip(vx, vy)[(0..).step(10)]
print(‘#2.1 #4.5 #2.8’.format(x, y, y - (4 + x * x) ^ 2 / 16))</langsyntaxhighlight>
 
{{out}}
Line 65:
9.0 451.56246 -0.00004072
10.0 675.99995 -0.00005098
</pre>
 
=={{header|Action!}}==
Calculations on a real Atari 8-bit computer take quite long time. It is recommended to use an emulator capable with increasing speed of Atari CPU.
{{libheader|Action! Tool Kit}}
{{libheader|Action! Real Math}}
<syntaxhighlight lang="action!">INCLUDE "D2:PRINTF.ACT" ;from the Action! Tool Kit
INCLUDE "H6:REALMATH.ACT"
 
DEFINE PTR="CARD"
 
REAL one,two,four,six
 
PROC Init()
IntToReal(1,one)
IntToReal(2,two)
IntToReal(4,four)
IntToReal(6,six)
RETURN
 
PROC Fun=*(REAL POINTER x,y,res)
DEFINE JSR="$20"
DEFINE RTS="$60"
[JSR $00 $00 ;JSR to address set by SetFun
RTS]
 
PROC SetFun(PTR p)
PTR addr
 
addr=Fun+1 ;location of address of JSR
PokeC(addr,p)
RETURN
 
PROC Rate(REAL POINTER x,y,res)
REAL tmp
Sqrt(y,tmp) ;tmp=sqrt(y)
RealMult(x,tmp,res) ;res=x*sqrt(y)
RETURN
 
PROC RK4(PTR f REAL POINTER dx,x,y,res)
REAL k1,k2,k3,k4,dx2,k12,k22,tmp1,tmp2,tmp3
 
SetFun(f)
Fun(x,y,tmp1) ;tmp1=f(x,y)
RealMult(dx,tmp1,k1) ;k1=dx*f(x,y)
 
RealDiv(dx,two,dx2) ;dx2=dx/2
RealDiv(k1,two,k12) ;k12=k1/2
RealAdd(x,dx2,tmp1) ;tmp1=x+dx/2
RealAdd(y,k12,tmp2) ;tmp2=y+k1/2
Fun(tmp1,tmp2,tmp3) ;tmp3=f(x+dx/2,y+k1/2)
RealMult(dx,tmp3,k2) ;k2=dx*f(x+dx/2,y+k1/2)
 
RealDiv(k2,two,k22) ;k22=k2/2
RealAdd(y,k22,tmp2) ;tmp2=y+k2/2
Fun(tmp1,tmp2,tmp3) ;tmp3=f(x+dx/2,y+k2/2)
RealMult(dx,tmp3,k3) ;k3=dx*f(x+dx/2,y+k2/2)
 
RealAdd(x,dx,tmp1) ;tmp1=x+dx
RealAdd(y,k3,tmp2) ;tmp2=y+k3
Fun(tmp1,tmp2,tmp3) ;tmp3=f(x+dx,y+k3)
RealMult(dx,tmp3,k4) ;k4=dx*f(x+dx,y+k3)
 
RealAdd(k2,k3,tmp1) ;tmp1=k2+k3
RealMult(two,tmp1,tmp2) ;tmp2=2*k2+2*k3
RealAdd(k1,tmp2,tmp1) ;tmp3=k1+2*k2+2*k3
RealAdd(tmp1,k4,tmp2) ;tmp2=k1+2*k2+2*k3+k4
RealDiv(tmp2,six,tmp1) ;tmp1=(k1+2*k2+2*k3+k4)/6
RealAdd(y,tmp1,res) ;res=y+(k1+2*k2+2*k3+k4)/6
RETURN
 
PROC Calc(REAL POINTER x,res)
REAL tmp1,tmp2
 
RealMult(x,x,tmp1) ;tmp1=x*x
RealDiv(tmp1,four,tmp2) ;tmp2=x*x/4
RealAdd(tmp2,one,tmp1) ;tmp1=x*x/4+1
Power(tmp1,two,res) ;res=(x*x/4+1)^2
RETURN
 
PROC RelError(REAL POINTER a,b,res)
REAL tmp
 
RealDiv(a,b,tmp) ;tmp=a/b
RealSub(tmp,one,res) ;res=a/b-1
RETURN
 
PROC Main()
REAL x0,x1,x,dx,y,y2,err,tmp1,tmp2
CHAR ARRAY s(20)
INT i,n
 
Put(125) PutE() ;clear the screen
MathInit()
Init()
PrintF("%-2S %-11S %-8S%E","x","y","rel err")
 
IntToReal(0,x0)
IntToReal(10,x1)
ValR("0.1",dx)
 
RealSub(x1,x0,tmp1) ;tmp1=x1-x0
RealDiv(tmp1,dx,tmp2) ;tmp2=(x1-x0)/dx
n=RealToInt(tmp2) ;n=(x1-x0)/dx
i=0
IntToReal(1,y)
DO
IntToReal(i,tmp1) ;tmp1=i
RealMult(dx,tmp1,tmp2) ;tmp2=i*dx
RealAdd(x0,tmp2,x) ;x=x0+i*dx
IF i MOD 10=0 THEN
Calc(x,y2)
RelError(y,y2,err)
StrR(x,s) PrintF("%-2S ",s)
StrR(y,s) PrintF("%-11S ",s)
StrR(err,s) PrintF("%-8S%E",s)
FI
 
i==+1
IF i>n THEN EXIT FI
 
RK4(rate,dx,x,y,tmp1) ;tmp1=rk4(rate,dx,x0+dx*(i-1),y)
RealAssign(tmp1,y) ;y=rk4(rate,dx,x0+dx*(i-1),y)
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Runge-Kutta_method.png Screenshot from Atari 8-bit computer]
<pre>
x y rel err
0 1 0
1 1.56249977 -1.3E-07
2 3.99999882 -2.9E-07
3 10.56249647 -2.9E-07
4 24.99999228 -2.9E-07
5 52.56248607 -2.0E-07
6 99.99997763 -2.1E-07
7 175.562459 -1.8E-07
8 288.999935 -1.9E-07
9 451.562406 0
10 675.999869 -1.4E-07
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
procedure RungeKutta is
Line 119 ⟶ 261:
Runge (yprime'Access, t_arr, y_arr, dt);
Print (t_arr, y_arr, 10);
end RungeKutta;</langsyntaxhighlight>
{{out}}
<pre>y(0.0) = 1.00000000 Error: 0.00000E+00
Line 134 ⟶ 276:
 
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">
<lang ALGOL68>
BEGIN
PROC rk4 = (PROC (REAL, REAL) REAL f, REAL y, x, dx) REAL :
Line 161 ⟶ 303:
OD
END
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 181 ⟶ 323:
{{Trans|ALGOL 68}}
As originally defined, the signature of a procedure parameter could not be specified in Algol W (as here), modern compilers may require parameter specifications for the "f" parameter of rk4.
<langsyntaxhighlight lang="algolw">begin
real procedure rk4 ( real procedure f ; real value y, x, dx ) ;
begin % Fourth-order Runge-Kutta method %
Line 210 ⟶ 352:
end for_i
end
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 228 ⟶ 370:
 
=={{header|APL}}==
<syntaxhighlight lang="apl">
<lang APL>
∇RK4[⎕]∇
Line 250 ⟶ 392:
[2] ⎕←'T' 'RK4 Y' 'ERROR'⍪TABLE,TABLE[;2]-{((4+⍵*2)*2)÷16}TABLE[;1]
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 269 ⟶ 411:
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f RUNGE-KUTTA_METHOD.AWK
# converted from BBC BASIC
Line 289 ⟶ 431:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 307 ⟶ 449:
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
<syntaxhighlight lang="basic256">y = 1
for i = 0 to 100
t = i / 10
 
if t = int(t) then
actual = ((t ^ 2 + 4) ^ 2) / 16
print "y("; int(t); ") = "; left(string(y), 13), "Error = "; left(string(actual - y), 13)
end if
 
k1 = t * sqr(y)
k2 = (t + 0.05) * sqr(y + 0.05 * k1)
k3 = (t + 0.05) * sqr(y + 0.05 * k2)
k4 = (t + 0.10) * sqr(y + 0.10 * k3)
y = y + 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
next i
end</syntaxhighlight>
 
 
==={{header|BBC BASIC}}===
<langsyntaxhighlight lang="bbcbasic"> y = 1.0
FOR i% = 0 TO 100
t = i% / 10
Line 322 ⟶ 483:
k4 = (t + 0.10) * SQR(y + 0.10 * k3)
y += 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
NEXT i%</langsyntaxhighlight>
{{out}}
<pre>y(0) = 1 Error = 0
Line 338 ⟶ 499:
 
==={{header|IS-BASIC}}===
<langsyntaxhighlight ISlang="is-BASICbasic">100 PROGRAM "Runge.bas"
110 LET Y=1
120 FOR T=0 TO 10 STEP .1
Line 347 ⟶ 508:
170 LET K4=(T+.1)*SQR(Y+.1*K3)
180 LET Y=Y+.1*(K1+2*(K2+K3)+K4)/6
190 NEXT</langsyntaxhighlight>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">y! = 1
FOR i = 0 TO 100
t = i / 10
 
IF t = INT(t) THEN
actual! = ((t ^ 2 + 4) ^ 2) / 16
PRINT USING "y(##) = ###.###### Error = "; t; y;
PRINT actual - y
END IF
 
k1! = t * SQR(y)
k2! = (t + .05) * SQR(y + .05 * k1)
k3! = (t + .05) * SQR(y + .05 * k2)
k4! = (t + .1) * SQR(y + .1 * k3)
y = y + .1 * (k1 + 2 * (k2 + k3) + k4) / 6
NEXT i</syntaxhighlight>
 
==={{header|True BASIC}}===
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">LET y = 1
FOR i = 0 TO 100
LET t = i / 10
 
IF t = INT(t) THEN
LET actual = ((t ^ 2 + 4) ^ 2) / 16
PRINT "y("; STR$(t); ") ="; y ; TAB(20); "Error = "; actual - y
END IF
 
LET k1 = t * SQR(y)
LET k2 = (t + 0.05) * SQR(y + 0.05 * k1)
LET k3 = (t + 0.05) * SQR(y + 0.05 * k2)
LET k4 = (t + 0.10) * SQR(y + 0.10 * k3)
LET Y = Y + 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
NEXT i
END</syntaxhighlight>
 
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 386 ⟶ 587:
 
return 0;
}</langsyntaxhighlight>
{{out}} (errors are relative)
<pre>
Line 405 ⟶ 606:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">
using System;
 
Line 499 ⟶ 700:
}
}
}</langsyntaxhighlight>
 
=={{header|C++}}==
Using Lambdas
<langsyntaxhighlight lang="cpp">/*
* compiled with:
* g++ (Debian 8.3.0-6) 8.3.0
Line 536 ⟶ 737:
for (
doubleauto y { Y_START }, t { T_START };
t <= TIME_MAXIMUM;
y += dy(t,y,DT), t += DT
Line 544 ⟶ 745:
return 0;
}</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
 
<langsyntaxhighlight lang="lisp">(defun runge-kutta (f x y x-end n)
(let ((h (float (/ (- x-end x) n) 1d0))
k1 k2 k3 k4)
Line 579 ⟶ 780:
(7.999999999999988d0 288.9999684347983d0 -3.156520000402452d-5)
(8.999999999999984d0 451.56245927683887d0 -4.072315812209126d-5)
(9.99999999999998d0 675.9999490167083d0 -5.0983286655537086d-5))</langsyntaxhighlight>
 
=={{header|Crystal}}==
{{trans|Run Basic and Ruby output}}
<langsyntaxhighlight lang="ruby">y, t = 1, 0
while t <= 10
k1 = t * Math.sqrt(y)
Line 593 ⟶ 794:
y += 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
t += 0.1
end</langsyntaxhighlight>
 
{{out}}
Line 612 ⟶ 813:
=={{header|D}}==
{{trans|Ada}}
<langsyntaxhighlight lang="d">import std.stdio, std.math, std.typecons;
 
alias FP = real;
Line 649 ⟶ 850:
t_arr[i], y_arr[i],
calc_err(t_arr[i], y_arr[i]));
}</langsyntaxhighlight>
{{out}}
<pre>y(0.0) = 1.00000000 Error: 0
Line 664 ⟶ 865:
 
=={{header|Dart}}==
<langsyntaxhighlight lang="dart">import 'dart:math' as Math;
 
num RungeKutta4(Function f, num t, num y, num dt){
Line 690 ⟶ 891:
t += dt;
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 705 ⟶ 906:
y(10.0) = 675.99994902 Error = 7.5419063100e-8
</pre>
 
=={{header|EasyLang}}==
{{trans|BASIC256}}
<syntaxhighlight>
numfmt 6 0
y = 1
for i = 0 to 100
t = i / 10
if t = floor t
h = t * t + 4
actual = h * h / 16
print "y(" & t & ") = " & y & " Error = " & actual - y
.
k1 = t * sqrt y
k2 = (t + 0.05) * sqrt (y + 0.05 * k1)
k3 = (t + 0.05) * sqrt (y + 0.05 * k2)
k4 = (t + 0.10) * sqrt (y + 0.10 * k3)
y += 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
.
</syntaxhighlight>
 
=={{header|EDSAC order code}}==
Line 712 ⟶ 933:
 
G1 can solve equations in several variables, say y_1, ..., y_n. The user must provide an auxiliary subroutine which calculates dy_1/dt, ..., dy_n/dt from y_1, ..., y_n. If the derivatives also depend on t (as in the Rosetta Code task) it's necessary to add a dummy y variable which is identical with t.
<langsyntaxhighlight lang="edsac">
[Demo of EDSAC library subroutine G1: Runge-Kutta solution of differential equations.
Full description is in Wilkes, Wheeler & Gill, 1951 edn, pages 32-34, 86-87, 132-134.
Line 857 ⟶ 1,078:
E25K TA GK
E10Z PF [enter at relative address 10 with accumulator = 0]
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 876 ⟶ 1,097:
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM RUNGE_KUTTA
 
Line 901 ⟶ 1,122:
Y+=DELTA_T*(K1+2*(K2+K3)+K4)/6
END FOR
END PROGRAM</langsyntaxhighlight>
{{out}}
<pre>
Line 915 ⟶ 1,136:
Y( 9 )= 451.5625 Error= 0
Y( 10 )= 676.0001 Error=-6.103516E-05
</pre>
 
=={{header|Excel}}==
<syntaxhighlight lang="Excel">
//Worksheet formula to manage looping
 
=LET(
T₊, SEQUENCE(11, 1, 0, 1),
T, DROP(T₊, -1),
τ, SEQUENCE(1 / δt, 1, 0, δt),
calculated, SCAN(1, T, LAMBDA(y₀, t, REDUCE(y₀, t + τ, RungaKutta4λ(Dλ)))),
calcs, VSTACK(1, calculated),
exact, f(T₊),
HSTACK(T₊, calcs, exact, (exact - calcs) / exact)
)
 
//Lambda function passed to RungaKutta4λ to evaluate derivatives
 
Dλ(y,t)
= LAMBDA(y,t, t * SQRT(y))
 
//Curried Lambda function with derivative function D and y, t as parameters
 
RungaKutta4λ(Dλ)
= LAMBDA(D,
LAMBDA(yᵣ, tᵣ,
LET(
δy₁, δt * D(yᵣ, tᵣ),
δy₂, δt * D(yᵣ + δy₁ / 2, tᵣ + δt / 2),
δy₃, δt * D(yᵣ + δy₂ / 2, tᵣ + δt / 2),
δy₄, δt * D(yᵣ + δy₃, tᵣ + δt),
yᵣ₊₁, yᵣ + (δy₁ + 2 * δy₂ + 2 * δy₃ + δy₄) / 6,
yᵣ₊₁
)
)
)
 
//Lambda function returning the exact solution
 
f(t)
= LAMBDA(t, (1/16) * (t^2 + 4)^2 )
</syntaxhighlight>
 
{{out}}
<pre>
Time Calculated Exact Rel Error
0.00 1.000000 1.000000 0.00E+00
1.00 1.562500 1.562500 9.33E-08
2.00 3.999999 4.000000 2.30E-07
3.00 10.562497 10.562500 2.75E-07
4.00 24.999994 25.000000 2.49E-07
5.00 52.562489 52.562500 2.06E-07
6.00 99.999983 100.000000 1.66E-07
7.00 175.562476 175.562500 1.34E-07
8.00 288.999968 289.000000 1.09E-07
9.00 451.562459 451.562500 9.02E-08
10.00 675.999949 676.000000 7.54E-08
</pre>
 
=={{header|F_Sharp|F#}}==
{{works with|F# interactive (fsi.exe)}}
<langsyntaxhighlight lang="fsharp">
open System
 
Line 940 ⟶ 1,218:
RungeKutta4 0.0 1.0 10.0 0.1
|> Seq.filter (fun (t,y) -> t % 1.0 = 0.0 )
|> Seq.iter (fun (t,y) -> Console.WriteLine("y({0})={1}\t(relative error:{2})", t, y, (y / y_exact(t))-1.0) )</langsyntaxhighlight>
 
{{out}}
Line 958 ⟶ 1,236:
 
=={{header|Fortran}}==
<langsyntaxhighlight lang="fortran">program rungekutta
implicit none
integer, parameter :: dp = kind(1d0)
Line 990 ⟶ 1,268:
f = t*sqrt(y)
end function f
end program rungekutta</langsyntaxhighlight>
{{out}}
<pre>
Line 1,008 ⟶ 1,286:
=={{header|FreeBASIC}}==
{{trans|BBC BASIC}}
<langsyntaxhighlight lang="freebasic">' version 03-10-2015
' compile with: fbc -s console
' translation of BBC BASIC
Line 1,038 ⟶ 1,316:
Print : Print "hit any key to end program"
Sleep
End</langsyntaxhighlight>
{{out}}
<pre>y(0) = 1 Error = 0
Line 1,053 ⟶ 1,331:
 
=={{header|FutureBasic}}==
<langsyntaxhighlight lang="futurebasic">window 1
include "ConsoleWindow"
 
def fn dydx( x as double, y as double ) as double = x * sqr(y)
def tab 9
def fn exactY( x as long ) as double = ( x ^2 + 4 ) ^2 / 16
 
long i
local fn dydx( x as double, y as double ) as double
double h, k1, k2, k3, k4, x, y, result
end fn = x * sqr(y)
local fn exactY( x as long ) as double
end fn = ( x ^2 + 4 ) ^2 / 16
 
dim as long i
dim as double h, k1, k2, k3, k4, x, y, result
 
h = 0.1
y = 1
for i = 0 to 100
x = i * h
if x == int(x)
result = fn exactY( x )
print "y("; mid$( str$(x), 2, len$(str$(x) )); ") = "; y, "Error = "; result - y
end if
k1 = h * fn dydx( x, y )
k2 = h * fn dydx( x + h / 2, y + k1 / 2 )
k3 = h * fn dydx( x + h / 2, y + k2 / 2 )
k4 = h * fn dydx( x + h, y + k3 )
 
y = y + 1 / 6 * ( k1 + 2 * k2 + 2 * k3 + k4 )
next
 
</lang>
HandleEvents</syntaxhighlight>
Output:
<pre>
Line 1,101 ⟶ 1,374:
=={{header|Go}}==
{{works with|Go1}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,157 ⟶ 1,430:
func printErr(t, y float64) {
fmt.Printf("y(%.1f) = %f Error: %e\n", t, y, math.Abs(actual(t)-y))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,174 ⟶ 1,447:
 
=={{header|Groovy}}==
<syntaxhighlight lang="groovy">
<lang Groovy>
class Runge_Kutta{
static void main(String[] args){
Line 1,199 ⟶ 1,472:
static def dy(def x){return x*0.1;}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,213 ⟶ 1,486:
y(9.0)=451.56245927683966 Error:4.07231603389846E-5
y(10.0)=675.9999490167097 Error:5.098329029351589E-5
</pre>
 
=={{header|Hare}}==
<syntaxhighlight lang="hare">use fmt;
use math;
 
export fn main() void = {
rk4_driver(&f, 0.0, 10.0, 1.0, 0.1);
};
 
fn rk4_driver(func: *fn(_: f64, _: f64) f64, t_init: f64, t_final: f64, y_init: f64, h: f64) void = {
let n = ((t_final - t_init) / h): int;
let tn: f64 = t_init;
let yn: f64 = y_init;
let i: int = 1;
 
fmt::printfln("{: 2} {: 18} {: 21}", "t", "y(t)", "absolute error")!;
fmt::printfln("{: 2} {: 18} {: 21}", tn, yn, math::absf64(exact(tn) - yn))!;
 
for (i <= n; i += 1) {
yn = rk4(func, tn, yn, h);
tn = t_init + (i: f64)*h;
 
if (i % 10 == 0) {
fmt::printfln("{: 2} {: 18} {: 21}\t", tn, yn, math::absf64(exact(tn) - yn))!;
};
};
};
 
fn rk4(func: *fn(_: f64, _: f64) f64, t: f64, y: f64, h: f64) f64 = {
const k1 = func(t, y);
const k2 = func(t + 0.5*h, y + 0.5*h*k1);
const k3 = func(t + 0.5*h, y + 0.5*h*k2);
const k4 = func(t + h, y + h*k3);
return y + h/6.0 * (k1 + 2.0*k2 + 2.0*k3 + k4);
};
 
fn f(t: f64, y: f64) f64 = {
return t * math::sqrtf64(y);
};
 
fn exact(t: f64) f64 = {
return 1.0/16.0 * math::powf64(t*t + 4.0, 2.0);
};</syntaxhighlight>
{{out}}
<pre>
t y(t) absolute error
0 1 0
1 1.562499854278108 1.4572189210859676e-7
2 3.9999990805207997 9.194792003341945e-7
3 10.56249709043755 2.909562450525982e-6
4 24.999993765090633 6.23490936746407e-6
5 52.56248918030258 1.0819697422448371e-5
6 99.99998340540358 1.659459641700778e-5
7 175.56247648227125 2.3517728749311573e-5
8 288.9999684347985 3.156520148195341e-5
9 451.5624592768396 4.072316039582802e-5
10 675.9999490167097 5.098329029351589e-5
</pre>
 
Line 1,219 ⟶ 1,550:
Using GHC 7.4.1.
 
<langsyntaxhighlight lang="haskell">dv
:: Floating a
=> a -> a -> a
Line 1,243 ⟶ 1,574:
(print . (\(x, y) -> (truncate x, y, fy x - y)))
(filter (\(x, _) -> 0 == mod (truncate $ 10 * x) 10) $
take 101 $ rk4 dv 1.0 0 0.1)</langsyntaxhighlight>
 
Example executed in GHCi:
<langsyntaxhighlight lang="haskell">*Main> task
(0,1.0,0.0)
(1,1.5624998542781088,1.4572189122041834e-7)
Line 1,257 ⟶ 1,588:
(8,288.99996843479926,3.1565204153594095e-5)
(9,451.562459276841,4.0723166534917254e-5)
(10,675.9999490167125,5.098330132113915e-5)</langsyntaxhighlight>
 
(See [[Euler method#Haskell]] for implementation of simple general ODE-solver)
Line 1,263 ⟶ 1,594:
 
Or, disaggregated a little, and expressed in terms of a single scanl:
<langsyntaxhighlight lang="haskell">rk4 :: Double -> Double -> Double -> Double
rk4 y x dx =
let f x y = x * sqrt y
Line 1,307 ⟶ 1,638:
where
justifyLeft n c s = take n (s ++ replicate n c)
justifyRight n c s = drop (length s) (replicate n c ++ s)</langsyntaxhighlight>
{{Out}}
<pre>y (0) = 1.0 ±0.0
Line 1,323 ⟶ 1,654:
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">NB.*rk4 a Solve function using Runge-Kutta method
NB. y is: y(ta) , ta , tb , tstep
NB. u is: function to solve
Line 1,340 ⟶ 1,671:
end.
T ,. Y
)</langsyntaxhighlight>
'''Example:'''
<langsyntaxhighlight lang="j"> fy=: (%16) * [: *: 4 + *: NB. f(t,y)
fyp=: (* %:)/ NB. f'(t,y)
report_whole=: (10 * i. >:10)&{ NB. report at whole-numbered t values
Line 1,358 ⟶ 1,689:
8 289 _3.15652e_5
9 451.562 _4.07232e_5
10 676 _5.09833e_5</langsyntaxhighlight>
 
'''Alternative solution:'''
 
The following solution replaces the for loop as well as the calculation of the increments (ks) with an accumulating suffix.
<langsyntaxhighlight lang="j">rk4=: adverb define
'Y0 a b h'=. 4{. y
T=. a + i.@>:&.(%&h) b-a
Line 1,379 ⟶ 1,710:
ks=. (x * [: u y + (* x&,))/\. tableau
({:y) + 6 %~ +/ 1 2 2 1 * ks
)</langsyntaxhighlight>
 
Use:
Line 1,387 ⟶ 1,718:
Translation of [[Runge-Kutta_method#Ada|Ada]] via [[Runge-Kutta_method#D|D]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import static java.lang.Math.*;
import java.util.function.BiFunction;
 
Line 1,424 ⟶ 1,755:
calc_err(t_arr[i], y_arr[i]));
}
}</langsyntaxhighlight>
 
<pre>y(0,0) = 1,00000000 Error: 0,000000
Line 1,440 ⟶ 1,771:
=={{header|JavaScript}}==
===ES5===
<syntaxhighlight lang="javascript">
<lang JavaScript>
function rk4(y, x, dx, f) {
var k1 = dx * f(x, y),
Line 1,477 ⟶ 1,808:
steps += 1;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,494 ⟶ 1,825:
 
===ES6===
<langsyntaxhighlight lang="javascript">(() => {
'use strict';
 
Line 1,656 ⟶ 1,987:
// MAIN ---
return main();
})();</langsyntaxhighlight>
{{Out}}
<pre>y (0) = 1.0 ± 0e+0
Line 1,674 ⟶ 2,005:
They use "while" and/or "until" as defined in recent versions of jq (after version 1.4).
To use either of the two programs with jq 1.4, simply include the lines in the following block:
<langsyntaxhighlight lang="jq">def until(cond; next):
def _until: if cond then . else (next|_until) end;
_until;
Line 1,680 ⟶ 2,011:
def while(cond; update):
def _while: if cond then ., (update | _while) else empty end;
_while;</langsyntaxhighlight>
 
===The Example Differential Equation and its Exact Solution===
<langsyntaxhighlight lang="jq"># yprime maps [t,y] to a number, i.e. t * sqrt(y)
def yprime: .[0] * (.[1] | sqrt);
Line 1,690 ⟶ 2,021:
. as $t
| (( $t*$t) + 4 )
| . * . / 16;</langsyntaxhighlight>
 
===dy/dt===
Line 1,696 ⟶ 2,027:
 
'''Generic filters:'''
<langsyntaxhighlight lang="jq"># n is the number of decimal places of precision
def round(n):
(if . < 0 then -1 else 1 end) as $s
Line 1,704 ⟶ 2,035:
 
# Is the input an integer?
def integerq: ((. - ((.+.01) | floor)) | abs) < 0.01;</langsyntaxhighlight>
 
'''dy(f)'''
<langsyntaxhighlight lang="jq">def dt: 0.1;
 
# Input: [t, y]; yp is a filter that accepts [t,y] as input
Line 1,720 ⟶ 2,051:
 
# Input: [t,y]
def dy(f): runge_kutta(f);</langsyntaxhighlight>
''' Example''':
<langsyntaxhighlight lang="jq"># state: [t,y]
[0,1]
| while( .[0] <= 10;
Line 1,731 ⟶ 2,062:
"y(\($t|round(1))) = \($y|round(10000)) ± \( ($t|actual) - $y | abs)"
else empty
end</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ time jq -r -n -f rk4.pl.jq
y(0) = 1 ± 0
y(1) = 1.5625 ± 1.4572189210859676e-07
Line 1,748 ⟶ 2,079:
real 0m0.048s
user 0m0.013s
sys 0m0.006s</langsyntaxhighlight>
 
===newRK4Step===
Line 1,759 ⟶ 2,090:
The heart of the program is the filter newRK4Step(yp), which is of type ypStepFunc and performs a single
step of the fourth-order Runge-Kutta method, provided yp is of type ypFunc.
<langsyntaxhighlight lang="jq"># Input: [t, y, dt]
def newRK4Step(yp):
.[0] as $t | .[1] as $y | .[2] as $dt
Line 1,801 ⟶ 2,132:
 
# main(t0; y0; tFinal; dtPrint)
main(0; 1; 10; 1)</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ time jq -n -r -f runge-kutta.jq
y(0) = 1 with error: 0
y(1) = 1.562499854278108 with error: 1.4572189210859676e-07
Line 1,818 ⟶ 2,149:
real 0m0.023s
user 0m0.014s
sys 0m0.006s</langsyntaxhighlight>
 
=={{header|Julia}}==
Line 1,825 ⟶ 2,156:
=== Using lambda expressions ===
{{trans|Python}}
<langsyntaxhighlight lang="julia">f(x, y) = x * sqrt(y)
theoric(t) = (t ^ 2 + 4.0) ^ 2 / 16.0
 
Line 1,847 ⟶ 2,178:
y += δy(t, y, δt)
t += δt
end</langsyntaxhighlight>
 
{{out}}
Line 1,864 ⟶ 2,195:
=== Alternative version ===
{{trans|Python}}
<langsyntaxhighlight lang="julia">function rk4(f::Function, x₀::Float64, y₀::Float64, x₁::Float64, n)
vx = Vector{Float64}(undef, n + 1)
vy = Vector{Float64}(undef, n + 1)
Line 1,884 ⟶ 2,215:
for (x, y) in Iterators.take(zip(vx, vy), 10)
@printf("%4.1f %10.5f %+12.4e\n", x, y, y - theoric(x))
end</langsyntaxhighlight>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
typealias Y = (Double) -> Double
Line 1,921 ⟶ 2,252:
val yd = fun(t: Double, yt: Double) = t * Math.sqrt(yt)
rungeKutta4(0.0, 10.0, 0.1, y, yd)
}</langsyntaxhighlight>
 
{{out}}
Line 1,941 ⟶ 2,272:
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
'[RC] Runge-Kutta method
'initial conditions
Line 1,973 ⟶ 2,304:
exactY=(x^2 + 4)^2 / 16
end function
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,989 ⟶ 2,320:
</pre>
 
=={{header|MathematicaLua}}==
<syntaxhighlight lang="lua">local df = function (t, y)
<lang Mathematica>(* Symbolic solution *)
-- derivative of function by value y at time t
return t*y^0.5
end
 
local dt = 0.1
local y = 1
 
print ("t", "realY"..' ', "y", ' '.."error")
print ("---", "-------"..' ', "---------------", ' '.."--------------------")
 
for i = 0, 100 do
local t = i*dt
if t%1 == 0 then
local realY = (t*t+4)^2/16
print (t, realY..' ', y, ' '..realY-y)
end
local dy1 = df(t, y)
local dy2 = df(t+dt/2, y+dt/2*dy1)
local dy3 = df(t+dt/2, y+dt/2*dy2)
local dy4 = df(t+dt, y+dt*dy3)
y = y + dt*(dy1+2*dy2+2*dy3+dy4)/6
end</syntaxhighlight>
{{Out}}
<pre>t realY y error
--- ------- --------------- --------------------
0.0 1.0 1 0.0
1.0 1.5625 1.5624998542781 1.457218921086e-007
2.0 4.0 3.9999990805208 9.1947919989011e-007
3.0 10.5625 10.562497090438 2.9095624469733e-006
4.0 25.0 24.999993765091 6.2349093639114e-006
5.0 52.5625 52.562489180303 1.0819697415343e-005
6.0 100.0 99.999983405404 1.6594596417008e-005
7.0 175.5625 175.56247648227 2.3517728749312e-005
8.0 289.0 288.9999684348 3.156520142511e-005
9.0 451.5625 451.56245927684 4.0723160338985e-005
10.0 676.0 675.99994901671 5.0983290293516e-005
 
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">(* Symbolic solution *)
DSolve[{y'[t] == t*Sqrt[y[t]], y[0] == 1}, y, t]
Table[{t, 1/16 (4 + t^2)^2}, {t, 0, 10}]
Line 2,009 ⟶ 2,381:
solution = NestList[phi, {0, 1}, 101];
Table[{y[[1]], y[[2]], Abs[y[[2]] - 1/16 (y[[1]]^2 + 4)^2]},
{y, solution[[1 ;; 101 ;; 10]]}] </syntaxhighlight>
</lang>
 
=={{header|MATLAB}}==
The normally-used built-in solver is the ode45 function, which uses a non-fixed-step solver with 4th/5th order Runge-Kutta methods. The MathWorks Support Team released a [http://www.mathworks.com/matlabcentral/answers/98293-is-there-a-fixed-step-ordinary-differential-equation-ode-solver-in-matlab-8-0-r2012b#answer_107643 package of fixed-step RK method ODE solvers] on MATLABCentral. The ode4 function contained within uses a 4th-order Runge-Kutta method. Here is code that tests both ode4 and my own function, shows that they are the same, and compares them to the exact solution.
<langsyntaxhighlight MATLABlang="matlab">function testRK4Programs
figure
hold on
Line 2,050 ⟶ 2,421:
y(k+1) = y(k)+(dy1+2*dy2+2*dy3+dy4)/6;
end
end</langsyntaxhighlight>
{{out}}
<pre>
Line 2,068 ⟶ 2,439:
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">/* Here is how to solve a differential equation */
'diff(y, x) = x * sqrt(y);
ode2(%, y, x);
Line 2,107 ⟶ 2,478:
s: map(lambda([x], (x^2 + 4)^2 / 16), x)$
 
for i from 1 step 10 thru 101 do print(x[i], " ", y[i], " ", y[i] - s[i]);</langsyntaxhighlight>
 
=={{header|МК-61/52}}==
Line 2,122 ⟶ 2,493:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import math
 
proc fn(t, y: float): float =
Line 2,170 ⟶ 2,541:
 
rk(start = 0, stop = 10, step = 0.1)
cur_y += (dy1 + 2.0 * (dy2 + dy3) + dy4) </langsyntaxhighlight>
{{out}}
<pre>y(0.0) = 1.0, error = 0.0
Line 2,185 ⟶ 2,556:
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">class RungeKuttaMethod {
function : Main(args : String[]) ~ Nil {
x0 := 0.0; x1 := 10.0; dx := .1;
Line 2,220 ⟶ 2,591:
return x * y->SquareRoot();
}
}</langsyntaxhighlight>
 
Output:
Line 2,238 ⟶ 2,609:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let y' t y = t *. sqrt y
let exact t = let u = 0.25*.t*.t +. 1.0 in u*.u
 
Line 2,253 ⟶ 2,624:
if n < 102 then loop h (n+1) (rk4_step (y,t) h)
 
let _ = loop 0.1 1 (1.0, 0.0)</langsyntaxhighlight>
{{out}}
<pre>t = 0.000000, y = 1.000000, err = 0
Line 2,268 ⟶ 2,639:
 
=={{header|Octave}}==
<langsyntaxhighlight lang="octave">
#Applying the Runge-Kutta method (This code must be implement on a different file than the main one).
 
Line 2,298 ⟶ 2,669:
fprintf('%d \t %.5f \t %.5f \t %.4g \n',i,f(i),Yn(1+i*10),f(i)-Yn(1+i*10));
endfor
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,316 ⟶ 2,687:
=={{header|PARI/GP}}==
{{trans|C}}
<langsyntaxhighlight lang="parigp">rk4(f,dx,x,y)={
my(k1=dx*f(x,y), k2=dx*f(x+dx/2,y+k1/2), k3=dx*f(x+dx/2,y+k2/2), k4=dx*f(x+dx,y+k3));
y + (k1 + 2*k2 + 2*k3 + k4) / 6
Line 2,331 ⟶ 2,702:
)
};
go()</langsyntaxhighlight>
{{out}}
<pre>x y rel. err.
Line 2,351 ⟶ 2,722:
This code has been compiled using Free Pascal 2.6.2.
 
<langsyntaxhighlight lang="pascal">program RungeKuttaExample;
 
uses sysutils;
Line 2,421 ⟶ 2,792:
RungeKutta(@YPrime, tArr, yArr, dt);
Print(tArr, yArr, 10);
end.</langsyntaxhighlight>
{{out}}
<pre>y( 0.0) = 1.00000000 Error: 0.00000E+000
Line 2,443 ⟶ 2,814:
 
Notice how we have to use sprintf to deal with floating point rounding. See perlfaq4.
<langsyntaxhighlight lang="perl">sub runge_kutta {
my ($yp, $dt) = @_;
sub {
Line 2,464 ⟶ 2,835:
printf "y(%2.0f) = %12f ± %e\n", $t, $y, abs($y - ($t**2 + 4)**2 / 16)
if sprintf("%.4f", $t) =~ /0000$/;
}</langsyntaxhighlight>
 
{{out}}
Line 2,481 ⟶ 2,852:
=={{header|Phix}}==
{{trans|ERRE}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant dt = 0.1
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
atom y = 1.0
<span style="color: #008080;">constant</span> <span style="color: #000000;">dt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0.1</span>
printf(1," x true/actual y calculated y relative error\n")
<span style="color: #004080;">atom</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1.0</span>
printf(1," --- ------------- ------------- --------------\n")
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" x true/actual y calculated y relative error\n"</span><span style="color: #0000FF;">)</span>
for i=0 to 100 do
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" --- ------------- ------------- --------------\n"</span><span style="color: #0000FF;">)</span>
atom t = i*dt
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100</span> <span style="color: #008080;">do</span>
if integer(t) then
<span style="color: #004080;">atom</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dt</span>
atom act = power(t*t+4,2)/16
<span style="color: #008080;">if</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
printf(1,"%4.1f %14.9f %14.9f %.9e\n",{t,act,y,abs(y-act)})
<span style="color: #004080;">atom</span> <span style="color: #000000;">act</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">*</span><span style="color: #000000;">t</span><span style="color: #0000FF;">+</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">16</span>
end if
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%4.1f %14.9f %14.9f %.9e\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">act</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">act</span><span style="color: #0000FF;">)})</span>
atom k1 = t*sqrt(y),
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
k2 = (t+dt/2)*sqrt(y+dt/2*k1),
<span style="color: #004080;">atom</span> <span style="color: #000000;">k1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">),</span>
k3 = (t+dt/2)*sqrt(y+dt/2*k2),
<span style="color: #000000;">k2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">k1</span><span style="color: #0000FF;">),</span>
k4 = (t+dt)*sqrt(y+dt*k3)
<span style="color: #000000;">k3</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">k2</span><span style="color: #0000FF;">),</span>
y += dt*(k1+2*(k2+k3)+k4)/6
<span style="color: #000000;">k4</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dt</span><span style="color: #0000FF;">)*</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dt</span><span style="color: #0000FF;">*</span><span style="color: #000000;">k3</span><span style="color: #0000FF;">)</span>
end for</lang>
<span style="color: #000000;">y</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">dt</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">k1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">k2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">k3</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">k4</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">6</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,515 ⟶ 2,889:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
Runge_Kutta: procedure options (main); /* 10 March 2014 */
declare (y, dy1, dy2, dy3, dy4) float (18);
Line 2,541 ⟶ 2,915:
 
end Runge_kutta;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,561 ⟶ 2,935:
{{works with|PowerShell|4.0}}
 
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Runge-Kutta (${function:F}, ${function:y}, $y0, $t0, $dt, $tEnd) {
function RK ($tn,$yn) {
Line 2,598 ⟶ 2,972:
$tEnd = 10
Runge-Kutta F y $y0 $t0 $dt $tEnd
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 2,618 ⟶ 2,992:
=={{header|PureBasic}}==
{{trans|BBC Basic}}
<langsyntaxhighlight PureBasiclang="purebasic">EnableExplicit
Define.i i
Define.d y=1.0, k1=0.0, k2=0.0, k3=0.0, k4=0.0, t=0.0
Line 2,636 ⟶ 3,010:
Print("Press return to exit...") : Input()
EndIf
End</langsyntaxhighlight>
{{out}}
<pre>y( 0) = 1.0000 Error = 0.0000000000
Line 2,652 ⟶ 3,026:
 
=={{header|Python}}==
<syntaxhighlight lang="python">from math import sqrt
===using lambda===
<lang Python>def RK4(f):
return lambda t, y, dt: (
lambda dy1: (
lambda dy2: (
lambda dy3: (
lambda dy4: (dy1 + 2*dy2 + 2*dy3 + dy4)/6
)( dt * f( t + dt , y + dy3 ) )
)( dt * f( t + dt/2, y + dy2/2 ) )
)( dt * f( t + dt/2, y + dy1/2 ) )
)( dt * f( t , y ) )
def theory(t): return (t**2 + 4)**2 /16
from math import sqrt
dy = RK4(lambda t, y: t*sqrt(y))
t, y, dt = 0., 1., .1
while t <= 10:
if abs(round(t) - t) < 1e-5:
print("y(%2.1f)\t= %4.6f \t error: %4.6g" % ( t, y, abs(y - theory(t))))
t, y = t + dt, y + dy( t, y, dt )
 
</lang>
{{Out}}
<pre>y(0.0) = 1.000000 error: 0
y(1.0) = 1.562500 error: 1.45722e-07
y(2.0) = 3.999999 error: 9.19479e-07
y(3.0) = 10.562497 error: 2.90956e-06
y(4.0) = 24.999994 error: 6.23491e-06
y(5.0) = 52.562489 error: 1.08197e-05
y(6.0) = 99.999983 error: 1.65946e-05
y(7.0) = 175.562476 error: 2.35177e-05
y(8.0) = 288.999968 error: 3.15652e-05
y(9.0) = 451.562459 error: 4.07232e-05
y(10.0) = 675.999949 error: 5.09833e-05</pre>
 
=== Alternate solution ===
 
<lang python>from math import sqrt
def rk4(f, x0, y0, x1, n):
Line 2,725 ⟶ 3,060:
8.0 288.99997 -3.1565e-05
9.0 451.56246 -4.0723e-05
10.0 675.99995 -5.0983e-05</langsyntaxhighlight>
 
=={{header|R}}==
 
<langsyntaxhighlight lang="r">rk4 <- function(f, x0, y0, x1, n) {
vx <- double(n + 1)
vy <- double(n + 1)
Line 2,760 ⟶ 3,095:
[9,] 8 288.999968 -3.156520e-05
[10,] 9 451.562459 -4.072316e-05
[11,] 10 675.999949 -5.098329e-05</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 2,767 ⟶ 3,102:
 
The Runge-Kutta method
<langsyntaxhighlight lang="racket">
(define (RK4 F δt)
(λ (t y)
Line 2,776 ⟶ 3,111:
(list (+ t δt)
(+ y (* 1/6 (+ δy1 (* 2 δy2) (* 2 δy3) δy4))))))
</syntaxhighlight>
</lang>
 
The method modifier which divides each time-step into ''n'' sub-steps:
<langsyntaxhighlight lang="racket">
(define ((step-subdivision n method) F h)
(λ (x . y) (last (ODE-solve F (cons x y)
Line 2,785 ⟶ 3,120:
#:step (/ h n)
#:method method))))
</syntaxhighlight>
</lang>
 
Usage:
<langsyntaxhighlight lang="racket">
(define (F t y) (* t (sqrt y)))
 
Line 2,799 ⟶ 3,134:
(match-define (list t y) s)
(printf "t=~a\ty=~a\terror=~a\n" t y (- y (exact-solution t))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,817 ⟶ 3,152:
Graphical representation:
 
<langsyntaxhighlight lang="racket">
> (require plot)
> (plot (list (function exact-solution 0 10 #:label "Exact solution")
(points numeric-solution #:label "Runge-Kutta method"))
#:x-label "t" #:y-label "y(t)")
</syntaxhighlight>
</lang>
[[File:runge-kutta.png]]
 
Line 2,828 ⟶ 3,163:
(formerly Perl 6)
{{Works with|rakudo|2016.03}}
<syntaxhighlight lang="raku" perl6line>sub runge-kutta(&yp) {
return -> \t, \y, \δt {
my $a = δt * yp( t, y );
Line 2,848 ⟶ 3,183:
printf "y(%2d) = %12f ± %e\n", $t, $y, abs($y - ($t**2 + 4)**2 / 16)
if $t %% 1;
}</langsyntaxhighlight>
{{out}}
<pre>y( 0) = 1.000000 ± 0.000000e+00
Line 2,863 ⟶ 3,198:
 
=={{header|REXX}}==
<pre>
The Runge─Kutta method is used to solve the following differential equation:
&nbsp;
<big><big> y'(t) = t<sup>2</sup> &radic;<span style="text-decoration: overline"> y(t) </span></big></big>
&nbsp;
The exact solution: <big><big> y(t) = (t<sup>2</sup>+4)<sup>2</sup> ÷ 16 </big></big>
 
 
╔═══════════════╗ ______ ╔══ the exact solution: y(t)= (t²+4)²/16 ══╗
<syntaxhighlight lang="rexx">/*REXX program uses the Runge─Kutta method to solve the equation: y'(t) = t² √[y(t)] */
╚═══════════════╝ y'(t)=t² √ y(t) ╚═══════════════════════════════════════════╝
</pre>
<lang rexx>/*REXX program uses the Runge─Kutta method to solve the equation: y'(t) = t² √[y(t)] */
numeric digits 40; f= digits() % 4 /*use 40 decimal digs, but only show 10*/
x0= 0; x1= 10; dx= .1 /*define variables: X0 X1 DX */
Line 2,896 ⟶ 3,233:
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g * .5'e'_ % 2
do j=0 while h>9; m.j=h; h=h%2+1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g</langsyntaxhighlight>
Programming note: &nbsp; the &nbsp; '''fmt''' &nbsp; function is used to
align the output with attention paid to the different ways some
Line 2,934 ⟶ 3,271:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
decimals(8)
y = 1.0
Line 2,948 ⟶ 3,285:
y += 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
next
</syntaxhighlight>
</lang>
 
Output:
Line 2,966 ⟶ 3,303:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def calc_rk4(f)
return ->(t,y,dt){
->(dy1 ){
Line 2,992 ⟶ 3,329:
printf("y(%4.1f)\t= %12.6f \t error: %12.6e\n",t,y,find_error(t,y)) if is_whole?(t)
t, y = t + DT, y + dy.call(t,y,DT)
end</langsyntaxhighlight>
{{Out}}
<pre>
Line 3,009 ⟶ 3,346:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight Runbasiclang="runbasic">y = 1
while t <= 10
k1 = t * sqr(y)
Line 3,020 ⟶ 3,357:
t = t + .1
wend
end</langsyntaxhighlight>
{{out}}
<pre>y( 0) = 1.0000000 Error =0
Line 3,037 ⟶ 3,374:
=={{header|Rust}}==
This is a translation of the javascript solution with some minor differences.
<langsyntaxhighlight lang="rust">fn runge_kutta4(fx: &dyn Fn(f64, f64) -> f64, x: f64, y: f64, dx: f64) -> f64 {
let k1 = dx * fx(x, y);
let k2 = dx * fx(x + dx / 2.0, y + k1 / 2.0);
Line 3,070 ⟶ 3,407:
x = ((x * 10.0) + (step * 10.0)) / 10.0;
}
}</langsyntaxhighlight>
<pre>
y(0): 1.0000000000 0E0
Line 3,086 ⟶ 3,423:
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">object Main extends App {
val f = (t: Double, y: Double) => t * Math.sqrt(y) // Runge-Kutta solution
val g = (t: Double) => Math.pow(t * t + 4, 2) / 16 // Exact solution
Line 3,112 ⟶ 3,449:
}
}
}</langsyntaxhighlight>
<pre>
y( 0.0) = 1.00000000 Error: 0.00000e+00
Line 3,129 ⟶ 3,466:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">func runge_kutta(yp) {
func (t, y, δt) {
var a = (δt * yp(t, y));
Line 3,149 ⟶ 3,486:
y += δy(t, y, δt);
t += δt;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,166 ⟶ 3,503:
 
=={{header|Standard ML}}==
<langsyntaxhighlight lang="sml">fun step y' (tn,yn) dt =
let
val dy1 = dt * y'(tn,yn)
Line 3,206 ⟶ 3,543:
 
(* Run the suggested test case *)
val () = test 0.0 1.0 0.1 101 10 testy testy'</langsyntaxhighlight>
{{out}}
<pre>Time: 0.0
Line 3,264 ⟶ 3,601:
 
=={{header|Stata}}==
<langsyntaxhighlight lang="stata">function rk4(f, t0, y0, t1, n) {
h = (t1-t0)/(n-1)
a = J(n, 2, 0)
Line 3,304 ⟶ 3,641:
10 | 9 451.5624593 -.0000407232 |
11 | 10 675.999949 -.0000509833 |
+----------------------------------------------+</langsyntaxhighlight>
 
=={{header|Swift}}==
{{trans|C}}
<langsyntaxhighlight Swiftlang="swift">import Foundation
 
func rk4(dx: Double, x: Double, y: Double, f: (Double, Double) -> Double) -> Double {
Line 3,345 ⟶ 3,682:
 
print(String(format: "%2g %11.6g %11.5g", x, y[i], y[i]/y2 - 1))
}</langsyntaxhighlight>
 
{{out}}
Line 3,363 ⟶ 3,700:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Hack to bring argument function into expression
Line 3,395 ⟶ 3,732:
printvals $t $y
}
}</langsyntaxhighlight>
{{out}}
<pre>y(0.0) = 1.00000000 Error: 0.00000000e+00
Line 3,408 ⟶ 3,745:
y(9.0) = 451.56245928 Error: 4.07231581e-05
y(10.0) = 675.99994902 Error: 5.09832864e-05</pre>
 
=={{header|V (Vlang)}}==
{{trans|Ring}}
<syntaxhighlight lang="Zig">
import math
 
fn main() {
mut t, mut k1, mut k2, mut k3, mut k4, mut y := 0.0, 0.0, 0.0, 0.0, 0.0, 1.0
for i in 0..101 {
t = i / 10.0
if t == math.floor(t) {
actual := math.pow((math.pow(t, 2) + 4), 2)/16
println("y(${t:.0}) = ${y:.8f} error = ${(actual - y):.8f}")
}
k1 = t * math.sqrt(y)
k2 = (t + 0.05) * math.sqrt(y + 0.05 * k1)
k3 = (t + 0.05) * math.sqrt(y + 0.05 * k2)
k4 = (t + 0.10) * math.sqrt(y + 0.10 * k3)
y += 0.1 * (k1 + 2 * (k2 + k3) + k4) / 6
}
}
</syntaxhighlight>
 
{{out}}
<pre>
y(0) = 1.00000000 error = 0.00000000
y(1) = 1.56249985 error = 0.00000015
y(2) = 3.99999908 error = 0.00000092
y(3) = 10.56249709 error = 0.00000291
y(4) = 24.99999377 error = 0.00000623
y(5) = 52.56248918 error = 0.00001082
y(6) = 99.99998341 error = 0.00001659
y(7) = 175.56247648 error = 0.00002352
y(8) = 288.99996843 error = 0.00003157
y(9) = 451.56245928 error = 0.00004072
y(10) = 675.99994902 error = 0.00005098
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var rungeKutta4 = Fn.new { |t0, tz, dt, y, yd|
Line 3,441 ⟶ 3,815:
}
var yd = Fn.new { |t, yt| t * yt.sqrt }
rungeKutta4.call(0, 10, 0.1, y, yd)</langsyntaxhighlight>
 
{{out}}
Line 3,458 ⟶ 3,832:
9.0 451.562459 451.562500 -0.000041
10.0 675.999949 676.000000 -0.000051
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">func real Y_(T, Y);
real T, Y;
return T*sqrt(Y);
 
def DT = 0.1;
real T, Y, Exact, DY1, DY2, DY3, DY4;
[Text(0, " T RK Exact Error^m^j");
T:= 0.; Y:= 1.;
repeat if Mod(T+.001, 1.) < .01 then
[Format(2, 1);
RlOut(0, T);
Format(5, 7);
RlOut(0, Y);
Exact:= sq(T*T+4.)/16.;
RlOut(0, Exact);
RlOut(0, Y-Exact);
CrLf(0);
];
DY1:= DT * Y_(T, Y);
DY2:= DT * Y_(T+DT/2., Y+DY1/2.);
DY3:= DT * Y_(T+DT/2., Y+DY2/2.);
DY4:= DT * Y_(T+DT, Y+DY3);
Y:= Y + (DY1 + 2.*DY2 + 2.*DY3 + DY4) / 6.;
T:= T + DT;
until T > 10.;
]</syntaxhighlight>
{{out}}
<pre>
T RK Exact Error
0.0 1.0000000 1.0000000 0.0000000
1.0 1.5624999 1.5625000 -0.0000001
2.0 3.9999991 4.0000000 -0.0000009
3.0 10.5624971 10.5625000 -0.0000029
4.0 24.9999938 25.0000000 -0.0000062
5.0 52.5624892 52.5625000 -0.0000108
6.0 99.9999834 100.0000000 -0.0000166
7.0 175.5624765 175.5625000 -0.0000235
8.0 288.9999684 289.0000000 -0.0000316
9.0 451.5624593 451.5625000 -0.0000407
10.0 675.9999490 676.0000000 -0.0000510
</pre>
 
=={{header|zkl}}==
{{trans|OCaml}}
<langsyntaxhighlight lang="zkl">fcn yp(t,y) { t * y.sqrt() }
fcn exact(t){ u:=0.25*t*t + 1.0; u*u }
Line 3,477 ⟶ 3,894:
print("t = %f,\ty = %f,\terr = %g\n".fmt(t,y,(y - exact(t)).abs()));
if(n < 102) return(loop(h,(n+1),rk4_step(T(y,t),h))) //tail recursion
}</langsyntaxhighlight>
{{out}}
<pre>
1,973

edits