Skip to content

Commit 96b2b5c

Browse files
Merge pull request #95 from rmsrosa/convergence_recipe
Δt-convergence plot recipe for WorkPrecisionSet
2 parents 66db958 + 3523fe8 commit 96b2b5c

File tree

5 files changed

+132
-16
lines changed

5 files changed

+132
-16
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
*.jl.*.cov
33
*.jl.mem
44
Manifest.toml
5+
6+
# vscode
7+
.vscode
8+
.vscode/*

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3535
SDEProblemLibrary = "c72e72a9-a271-4b2b-8966-303ed956772e"
3636
StochasticDelayDiffEq = "29a0d76e-afc8-11e9-03a4-eda52ae4b960"
3737
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"
38+
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
3839
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3940

4041
[targets]
41-
test = ["DelayDiffEq", "DDEProblemLibrary", "ODEProblemLibrary", "SDEProblemLibrary", "OrdinaryDiffEq", "ParameterizedFunctions", "Random", "StochasticDiffEq", "StochasticDelayDiffEq", "Test"]
42+
test = ["DelayDiffEq", "DDEProblemLibrary", "ODEProblemLibrary", "SDEProblemLibrary", "OrdinaryDiffEq", "ParameterizedFunctions", "Random", "StochasticDiffEq", "StochasticDelayDiffEq", "Plots", "Test"]

src/plotrecipes.jl

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,69 @@ end
3737
wp.errors, wp.times
3838
end
3939

40-
@recipe function f(wp_set::WorkPrecisionSet)
41-
seriestype --> :path
42-
linewidth --> 3
43-
yguide --> "Time (s)"
44-
xguide --> "Error"
45-
xscale --> :log10
46-
yscale --> :log10
47-
marker --> :auto
48-
errors = Vector{Any}(undef, 0)
49-
times = Vector{Any}(undef, 0)
50-
for i in 1:length(wp_set)
51-
push!(errors, wp_set[i].errors)
52-
push!(times, wp_set[i].times)
40+
@recipe function f(wp_set::WorkPrecisionSet; view = :benchmark, color = nothing)
41+
if view == :benchmark
42+
seriestype --> :path
43+
linewidth --> 3
44+
yguide --> "Time (s)"
45+
xguide --> "Error"
46+
xscale --> :log10
47+
yscale --> :log10
48+
marker --> :auto
49+
errors = Vector{Any}(undef, 0)
50+
times = Vector{Any}(undef, 0)
51+
for i in 1:length(wp_set)
52+
push!(errors, wp_set[i].errors)
53+
push!(times, wp_set[i].times)
54+
end
55+
label --> reshape(wp_set.names, 1, length(wp_set))
56+
return errors, times
57+
elseif view == :dt_convergence
58+
idts = filter(i -> haskey(wp_set.setups[i], :dts), 1:length(wp_set))
59+
length(idts) > 0 ||
60+
throw(ArgumentError("Convergence with respect to Δt requires runs with fixed time steps"))
61+
dts = Vector{Any}(undef, 0)
62+
errors = Vector{Any}(undef, 0)
63+
ps = Vector{Any}(undef, 0)
64+
convs = Vector{Any}(undef, 0)
65+
for i in idts
66+
push!(dts, wp_set.setups[i][:dts])
67+
push!(errors, wp_set[i].errors)
68+
lc, p = [one.(dts[end]) log.(dts[end])] \ log.(errors[end])
69+
push!(ps, p)
70+
push!(convs, exp(lc) * dts[end] .^ p)
71+
end
72+
names = wp_set.names[idts] .*
73+
map(p -> " (Δtᵖ order p=$(round(p, sigdigits=2)))", ps)
74+
if color === nothing
75+
color = reshape(1:length(idts), 1, :)
76+
end
77+
@series begin
78+
seriestype --> :path
79+
linestyle --> :dash
80+
linewidth --> 1
81+
color --> color
82+
xscale --> :log10
83+
yscale --> :log10
84+
markersize --> 0
85+
label --> nothing
86+
return dts, convs
87+
end
88+
@series begin
89+
seriestype --> :path
90+
linewidth --> 3
91+
color --> color
92+
yguide --> "Error"
93+
xguide --> "Δt"
94+
xscale --> :log10
95+
yscale --> :log10
96+
marker --> :auto
97+
label --> reshape(names, 1, length(idts))
98+
return dts, errors
99+
end
100+
else
101+
throw(ArgumentError("view argument `$view` not implemented"))
53102
end
54-
label --> reshape(wp_set.names, 1, length(wp_set))
55-
errors, times
56103
end
57104

58105
@recipe function f(tab::ODERKTableau; dx = 1 / 100, dy = 1 / 100, order_star = false,

test/plotrecipes_tests.jl

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using Test
2+
using OrdinaryDiffEq, DiffEqDevTools, Plots
3+
4+
using Random
5+
Random.seed!(123)
6+
7+
gr()
8+
9+
# Linear ODE system
10+
f_rode_lin = function (du, u, p, t)
11+
@inbounds for i in eachindex(u)
12+
du[i] = cos(t) * u[i]
13+
end
14+
end
15+
16+
f_rode_lin_analytic = function (u₀, p, t)
17+
u₀ * exp(sin(t))
18+
end
19+
20+
tspan = (0.0, 10.0)
21+
prob = ODEProblem(ODEFunction(f_rode_lin, analytic = f_rode_lin_analytic), rand(10, 10),
22+
tspan)
23+
24+
abstols = 1.0 ./ 10.0 .^ (3:8)
25+
reltols = 1.0 ./ 10.0 .^ (0:5)
26+
27+
setups = [Dict(:alg => DP5())
28+
Dict(:alg => Tsit5())]
29+
wp_names = ["DP5", "Tsit5"]
30+
wp = WorkPrecisionSet(prob, abstols, reltols, setups, names = wp_names,
31+
save_everystep = false,
32+
numruns = 100)
33+
34+
plt = @test_nowarn plot(wp)
35+
@test plt[1][1][:x] wp[1].errors
36+
@test plt[1][2][:x] wp[2].errors
37+
@test plt[1][1][:label] == wp_names[1]
38+
@test plt[1][2][:label] == wp_names[2]
39+
@test_nowarn plot(wp, color = [1 2])
40+
@test_nowarn plot(wp, color = :blue)
41+
@test_throws ArgumentError plot(wp, view = :dt_convergence)
42+
43+
dts = 1.0 ./ 2.0 .^ ((1:length(reltols)) .+ 1)
44+
setups = [Dict(:alg => Euler(), :dts => dts)
45+
Dict(:alg => Heun(), :dts => dts)
46+
Dict(:alg => Tsit5(), :dts => dts, :adaptive => false)
47+
Dict(:alg => Tsit5())]
48+
wp_names = ["Euler", "Heun", "Tsit5 fixed step", "Tsit5 adaptive"]
49+
wp = WorkPrecisionSet(prob, abstols, reltols, setups, names = wp_names,
50+
save_everystep = false,
51+
numruns = 100)
52+
53+
plt = @test_nowarn plot(wp)
54+
@test all(plt[1][i][:x] wp[i].errors for i in 1:4)
55+
@test all(plt[1][i][:label] == wp_names[i] for i in 1:4)
56+
57+
plt = @test_nowarn plot(wp, view = :dt_convergence, legend = :bottomright)
58+
@test all(plt[1][i][:x] == plt[1][i + 3][:x] == dts == wp.setups[i][:dts] for i in 1:3)
59+
@test all(plt[1][i + 3][:y] wp[i].errors for i in 1:3)
60+
@test all(startswith(plt[1][i + 3][:label], wp_names[i]) for i in 1:3)
61+
@test_throws BoundsError plt[1][7]
62+
@test_nowarn plot(wp, view = :dt_convergence, color = [:red :orange :green])
63+
@test_nowarn plot(wp, view = :dt_convergence, color = :lightblue, title = "Δt Convergence")

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ using Test
88
@time @testset "ODE Tableau Convergence Tests" begin include("ode_tableau_convergence_tests.jl") end ## Windows 32-bit fails on Butcher62 convergence test
99
@time @testset "Analyticless Stochastic WP" begin include("analyticless_stochastic_wp.jl") end
1010
@time @testset "Stability Region Tests" begin include("stability_region_test.jl") end
11+
@time @testset "Plot Recipes" begin include("plotrecipes_tests.jl") end

0 commit comments

Comments
 (0)