From e2bc69d2b41d12838495c2e93ba088925dfa6bc7 Mon Sep 17 00:00:00 2001 From: acroy Date: Tue, 4 Mar 2014 20:55:03 +0100 Subject: [PATCH] Some cosmetics & new test added (B5). --- src/ODE.jl | 14 +++++++------- test/perf_test.jl | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/ODE.jl b/src/ODE.jl index 435b591c4..b2193e1b8 100644 --- a/src/ODE.jl +++ b/src/ODE.jl @@ -208,14 +208,14 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, p: k[j,:] = F(t + h.*c[j], x + h.*(a[j,1:j-1]*k[1:j-1,:]).') end - # compute the 4th order estimate - x4 = x + h.*(bs*k).' + # compute the (p-1)th order estimate + xbs = x + h.*(bs*k).' - # compute the 5th order estimate - x5 = x + h.*(b*k).' + # compute the pth order estimate + xb = x + h.*(b*k).' # estimate the local truncation error - gamma1 = x5 - x4 + gamma1 = xb - xbs # Estimate the error and the acceptable error delta = norm(gamma1, Inf) # actual error @@ -224,14 +224,14 @@ function oderkf{T}(F::Function, tspan::AbstractVector, x0::AbstractVector{T}, p: # Update the solution only if the error is acceptable if delta <= tau t = t + h - x = x5 # <-- using the higher order estimate is called 'local extrapolation' + x = xb # <-- using the higher order estimate is called 'local extrapolation' tout = [tout; t] xout = [xout; x.'] # Compute the slopes by computing the k[:,j+1]'th column based on the previous k[:,1:j] columns # notes: k needs to end up as an Nxs, a is 7x6, which is s by (s-1), # s is the number of intermediate RK stages on [t (t+h)] (Dormand-Prince has s=7 stages) - if c[end] == 1 && t != tspan[1] + if c[end] == 1 # Assign the last stage for x(k) as the first stage for computing x[k+1]. # This is part of the Dormand-Prince pair caveat. # k[:,7] has already been computed, so use it instead of recomputing it diff --git a/test/perf_test.jl b/test/perf_test.jl index cf66ecf90..adaf67c5d 100644 --- a/test/perf_test.jl +++ b/test/perf_test.jl @@ -1,5 +1,6 @@ # comparison of adaptive methods + # adaptive solvers solvers = [ ODE.ode23, @@ -10,6 +11,7 @@ solvers = [ ODE.ode45_ck ] +println("\n== problem A3 in DETEST ==\n") for solver in solvers println("testing method $(string(solver))") @@ -26,4 +28,35 @@ for solver in solvers println("* maximal step: $(maximum(diff(t)))") println("* maximal deviation from known solution: $(maximum(abs(y[:]-exp(sin(t)))))\n") -end \ No newline at end of file +end + +# problem B5 in DETEST +# motion of a rigid body without external forces +# (see also Example 1 from http://www.mathworks.se/help/matlab/ref/ode45.html) +function rigid(t,y) + dy = copy(y) + dy[1] = y[2] * y[3] + dy[2] = -y[1] * y[3] + dy[3] = -0.51 * y[1] * y[2] + + return dy +end + +println("\n== problem B5 in DETEST ==\n") +for solver in solvers + println("testing method $(string(solver))") + + # problem B5 in DETEST + t,y = solver(rigid, [0.,12.], [0., 1., 1.]); + @time begin + for i=1:10 + t,y = solver(rigid, [0.,12.], [0., 1., 1.]); + end + end + + println("* number of steps: $(length(t))") + println("* minimal step: $(minimum(diff(t)))") + println("* maximal step: $(maximum(diff(t)))\n") + + # println("* maximal deviation from known solution: $(maximum(abs(y[:]-exp(sin(t)))))\n") +end