Runge-Kutta method: Difference between revisions

Added Hare
m (→‎{{header|Phix}}: syntax coloured)
(Added Hare)
Line 1,374:
y(9.0)=451.56245927683966 Error:4.07231603389846E-5
y(10.0)=675.9999490167097 Error:5.098329029351589E-5
</pre>
 
=={{header|Hare}}==
<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);
};</lang>
{{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>
 
22

edits