June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -21,7 +21,7 @@ int main(void)
double *y, x, y2;
double x0 = 0, x1 = 10, dx = .1;
int i, n = 1 + (x1 - x0)/dx;
y = malloc(sizeof(double) * n);
y = (double *)malloc(sizeof(double) * n);
for (y[0] = 1, i = 1; i < n; i++)
y[i] = rk4(rate, dx, x0 + dx * (i - 1), y[i-1]);

View file

@ -0,0 +1,23 @@
f(x, y) = x * sqrt(y)
theoric(t) = (t ^ 2 + 4.0) ^ 2 / 16.0
rk4(f) = (t, y, δt) -> # 1st (result) lambda
((δy1) -> # 2nd lambda
((δy2) -> # 3rd lambda
((δy3) -> # 4th lambda
((δy4) -> ( δy1 + 2δy2 + 2δy3 + δy4 ) / 6 # 5th and deepest lambda: calc y_{n+1}
)(δt * f(t + δt, y + δy3)) # calc δy₄
)(δt * f(t + δt / 2, y + δy2 / 2)) # calc δy₃
)(δt * f(t + δt / 2, y + δy1 / 2)) # calc δy₂
)(δt * f(t, y)) # calc δy₁
δy = rk4(f)
t₀, δt, tmax = 0.0, 0.1, 10.0
y₀ = 1.0
t, y = t₀, y₀
while t ≤ tmax
if t ≈ round(t) @printf("y(%4.1f) = %10.6f\terror: %12.6e\n", t, y, abs(y - theoric(t))) end
y += δy(t, y, δt)
t += δt
end

View file

@ -0,0 +1,21 @@
function rk4(f::Function, x₀::Float64, y₀::Float64, x₁::Float64, n)
vx = Vector{Float64}(n + 1)
vy = Vector{Float64}(n + 1)
vx[1] = x = x₀
vy[1] = y = y₀
h = (x₁ - x₀) / n
for i in 1:n
k₁ = h * f(x, y)
k₂ = h * f(x + 0.5h, y + 0.5k₁)
k₃ = h * f(x + 0.5h, y + 0.5k₂)
k₄ = h * f(x + h, y + k₃)
vx[i + 1] = x = x₀ + i * h
vy[i + 1] = y = y + (k₁ + 2k₂ + 2k₃ + k₄) / 6
end
return vx, vy
end
vx, vy = rk4(f, 0.0, 1.0, 10.0, 100)
for (x, y) in Iterators.take(zip(vx, vy), 10)
@printf("%4.1f %10.5f %+12.4e\n", x, y, y - theoric(x))
end

View file

@ -1,33 +0,0 @@
function rk4(f)
return (t,y,dt)->
( (dy1 )->
( (dy2 )->
( (dy3 )->
( (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 ) )
end
theory(t) = (t^2 + 4.0)^2 / 16.0
tmax = 10.0
ttol = 1.e-5
t0 = 0.0
y0 = 1.0
dt = 0.1
dy = rk4( (t,y) -> t*sqrt(y) )
t = t0
y = y0
while t <= tmax
if abs(round(t) - t) < ttol
@printf( STDOUT,"y(%4.1f)\t= %12.6f \t error: %12.6e\n",t,y,abs(y-theory(t)) )
end
y = y + dy(t,y,dt)
t = t + dt
end

View file

@ -0,0 +1,26 @@
import math
proc fn(t, y: float): float =
result = t * math.sqrt(y)
proc solution(t: float): float =
result = (t^2 + 4)^2 / 16
proc rk(start, stop, step: float) =
let nsteps = int(round((stop - start) / step)) + 1
let delta = (stop - start) / float(nsteps - 1)
var cur_y = 1.0
for i in 0..(nsteps - 1):
let cur_t = start + delta * float(i)
if abs(cur_t - math.round(cur_t)) < 1e-5:
echo "y(", cur_t, ") = ", cur_y, ", error = ", solution(cur_t) - cur_y
let dy1 = step * fn(cur_t, cur_y)
let dy2 = step * fn(cur_t + 0.5 * step, cur_y + 0.5 * dy1)
let dy3 = step * fn(cur_t + 0.5 * step, cur_y + 0.5 * dy2)
let dy4 = step * fn(cur_t + step, cur_y + dy3)
cur_y += (dy1 + 2.0 * (dy2 + dy3) + dy4) / 6.0
rk(start=0.0, stop=10.0, step=0.1)

View file

@ -1,8 +1,29 @@
function ydot = f(y, t)
ydot = t * sqrt( y );
#Applying the Runge-Kutta method (This code must be implement on a different file than the main one).
function temp = rk4(func,x,pvi,h)
K1 = h*func(x,pvi);
K2 = h*func(x+0.5*h,pvi+0.5*K1);
K3 = h*func(x+0.5*h,pvi+0.5*K2);
K4 = h*func(x+h,pvi+K3);
temp = pvi + (K1 + 2*K2 + 2*K3 + K4)/6;
endfunction
t = [0:10]';
y = lsode("f", 1, t);
#Main Program.
[ t, y, y - 1/16 * (t.**2 + 4).**2 ]
f = @(t) (1/16)*((t.^2 + 4).^2);
df = @(t,y) t*sqrt(y);
pvi = 1.0;
h = 0.1;
Yn = pvi;
for x = 0:h:10-h
pvi = rk4(df,x,pvi,h);
Yn = [Yn pvi];
endfor
fprintf('Time \t Exact Value \t ODE4 Value \t Num. Error\n');
for i=0:10
fprintf('%d \t %.5f \t %.5f \t %.4g \n',i,f(i),Yn(1+i*10),f(i)-Yn(1+i*10));
endfor

View file

@ -1,32 +1,28 @@
/*REXX program uses the Runge─Kutta method to solve the equation: y'(t)=t² √[y(t)] */
numeric digits 40; f=digits()%4 /*use 40 digits, but only show 1/4 that*/
x0=0; x1=10; w=digits()%2; dx= .1 /*set X0 & X1; calculate W & DX */
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 */
n=1 + (x1-x0) / dx
y.=1; do m=1 for n-1; mm=m-1
y.m=RK4(dx, x0+dx*mm, y.mm) /*use 4th order Runge─Kutta.*/
end /*m*/
y.=1; do m=1 for n-1; p=m-1; y.m=RK4(dx, x0 + dx*p, y.p)
end /*m*/ /* [↑] use 4th order Runge─Kutta. */
w=digits() % 2 /*W: width used for displaying numbers.*/
say center('X', f, "") center('Y', w+2, "") center("relative error", w+8, '') /*hdr*/
say center('X', f, "") center('Y', w+2, "") center("relative error", w+8, '')
do i=0 to n-1 by 10; x=(x0+dx*i)/1; $=y.i / (x*x/4+1)**2 - 1
say center(x,f) fmt(y.i) left('', 2 + ($>=0)) fmt($)
end /*i*/
do i=0 to n-1 by 10; x=(x0 + dx*i) / 1; $=y.i/(x*x/4+1)**2 -1
say center(x, f) fmt(y.i) left('', 2 + ($>=0) ) fmt($)
end /*i*/ /*└┴┴┴───◄─────── aligns positive #'s. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fmt: z=right( format( arg(1), w, f), w); hasE=pos('E', z)\==0 /*right adjust number.*/
if pos(.,z)\==0 & \hasE then z=left( strip( strip(z, 'T', 0), "T", .), w)
return translate(right(z, (z>=0) + w + 5*hasE), 'e', "E") /*Positive | E, adjust*/
fmt: z=right( format( arg(1), w, f), w); hasE=pos('E', z)\==0; has.=pos(., z)\==0
jus=has. & \hasE; if jus then z=left( strip( strip(z, 'T', 0), "T", .), w)
return translate(right(z, (z>=0) + w + 5*hasE + 2*(jus & (z<0) ) ), 'e', "E")
/*──────────────────────────────────────────────────────────────────────────────────────*/
rate: return arg(1) * sqrt( arg(2) ) /*compute the rate. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
RK4: procedure; parse arg dx,x,y; k1= dx * rate( x , y )
k2= dx * rate( x +dx/2 , y +k1/2 )
k3= dx * rate( x +dx/2 , y +k2/2 )
k4= dx * rate( x +dx , y +k3 )
return y + (k1 + k2+k2 + k3+k3 + k4) / 6
RK4: procedure; parse arg dx,x,y; dxH=dx/2; k1= dx * (x ) * sqrt(y )
k2= dx * (x + dxH) * sqrt(y + k1/2)
k3= dx * (x + dxH) * sqrt(y + k2/2)
k4= dx * (x + dx ) * sqrt(y + k3 )
return y + (k1 + k2*2 + k3*2 + k4) / 6
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); m.=9; numeric form; h=d+6
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*/
numeric digits d; return g/1
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

View file

@ -1,10 +1,10 @@
fn runge_kutta4( fx: &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 );
let k3 = dx * fx( x + dx / 2.0, y + k2 / 2.0 );
let k4 = dx * fx( x + dx, y + k3 );
fn runge_kutta4(fx: &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);
let k3 = dx * fx(x + dx / 2.0, y + k2 / 2.0);
let k4 = dx * fx(x + dx, y + k3);
y + ( k1 + 2.0 * k2 + 2.0 * k3 + k4 ) / 6.0
y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0
}
fn f(x: f64, y: f64) -> f64 {
@ -12,17 +12,17 @@ fn f(x: f64, y: f64) -> f64 {
}
fn actual(x: f64) -> f64 {
(1.0/16.0) * (x*x+4.0).powi(2)
(1.0 / 16.0) * (x * x + 4.0).powi(2)
}
fn main() {
let mut y = 1.0;
let mut x = 0.0;
let step = 0.1;
let mut steps = 0;
let max_steps = 101;
let sample_every_n = 10;
while steps < max_steps {
for steps in 0..max_steps {
if steps % sample_every_n == 0 {
println!("y({}):\t{:.10}\t\t {:E}", x, y, actual(x) - y)
}
@ -30,7 +30,5 @@ fn main() {
y = runge_kutta4(&f, x, y, step);
x = ((x * 10.0) + (step * 10.0)) / 10.0;
steps += 1;
}
}

View file

@ -0,0 +1,41 @@
function rk4(f, t0, y0, t1, n) {
h = (t1-t0)/(n-1)
a = J(n, 2, 0)
a[1, 1] = t = t0
a[1, 2] = y = y0
for (i=2; i<=n; i++) {
k1 = h*(*f)(t, y)
k2 = h*(*f)(t+0.5*h, y+0.5*k1)
k3 = h*(*f)(t+0.5*h, y+0.5*k2)
k4 = h*(*f)(t+h, y+k3)
t = t+h
y = y+(k1+2*k2+2*k3+k4)/6
a[i, 1] = t
a[i, 2] = y
}
return(a)
}
function f(t, y) {
return(t*sqrt(y))
}
a = rk4(&f(), 0, 1, 10, 101)
t = a[., 1]
a = a, a[., 2]:-(t:^2:+4):^2:/16
a[range(1,101,10), .]
1 2 3
+----------------------------------------------+
1 | 0 1 0 |
2 | 1 1.562499854 -1.45722e-07 |
3 | 2 3.999999081 -9.19479e-07 |
4 | 3 10.56249709 -2.90956e-06 |
5 | 4 24.99999377 -6.23491e-06 |
6 | 5 52.56248918 -.0000108197 |
7 | 6 99.99998341 -.0000165946 |
8 | 7 175.5624765 -.0000235177 |
9 | 8 288.9999684 -.0000315652 |
10 | 9 451.5624593 -.0000407232 |
11 | 10 675.999949 -.0000509833 |
+----------------------------------------------+