Skip to content

Commit c66f2ee

Browse files
Merge pull request #5 from control-toolbox/temp
Temp
2 parents 2fc9251 + d31e692 commit c66f2ee

18 files changed

+717
-18
lines changed

Project.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,30 @@ version = "0.1.0"
44
authors = ["Olivier Cots <olivier.cots@toulouse-inp.fr>"]
55

66
[deps]
7+
DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d"
78
DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63"
9+
DualNumbers = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
810
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
911
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
1012
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
13+
ODEInterface = "54ca160b-1b9f-5127-a996-1867f4bc2a2c"
14+
ODEInterfaceDiffEq = "09606e27-ecf5-54fc-bb29-004bd9f985bf"
15+
ODEProblemLibrary = "fdc4e326-1af4-4b90-96e7-779fcce2daa5"
1116
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
1217
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1318
SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1"
1419
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
1520

1621
[compat]
22+
DiffEqDevTools = "2.48.0"
1723
DifferentiationInterface = "0.7.9"
24+
DualNumbers = "0.6.9"
1825
ForwardDiff = "1.2.2"
1926
LaTeXStrings = "1.4.0"
2027
LinearAlgebra = "1.12.0"
28+
ODEInterface = "0.5.0"
29+
ODEInterfaceDiffEq = "3.13.5"
30+
ODEProblemLibrary = "1.2.2"
2131
OrdinaryDiffEq = "6.102.1"
2232
Plots = "1.41.1"
2333
SciMLSensitivity = "7.90.0"

article/figures/chris.jl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
###############################################################################
2+
# From https://github.com/SciML/ODE.jl/blob/master/src/ODE.jl
3+
# estimator for initial step based on book
4+
# "Solving Ordinary Differential Equations I" by Hairer et al., p.169
5+
#
6+
#function hinit(F, x0, t0::T, tend, p, reltol, abstol) where T
7+
function hinit(F, x0, t0, tend, p, reltol, abstol)
8+
# Returns first step, direction of integration and F evaluated at t0
9+
tdir = sign(tend-t0)
10+
tdir==0 && error("Zero time span")
11+
tau = max(reltol*norm(x0, Inf), abstol)
12+
d0 = norm(x0, Inf)/tau
13+
f0 = F(t0, x0)
14+
d1 = norm(f0, Inf)/tau
15+
if d0 < 1e-5 || d1 < 1e-5
16+
h0 = 1e-6
17+
else
18+
h0 = 0.01*(d0/d1)
19+
end
20+
# perform Euler step
21+
x1 = x0 + tdir*h0*f0
22+
f1 = F(t0 + tdir*h0, x1)
23+
# estimate second derivative
24+
d2 = norm(f1 - f0, Inf)/(tau*h0)
25+
if max(d1, d2) <= 1e-15
26+
h1 = max((10)^(-6), (10)^(-3)*h0)
27+
else
28+
pow = -(2 + log10(max(d1, d2)))/(p + 1)
29+
h1 = 10^pow
30+
end
31+
32+
return tdir*min(100*h0, h1, tdir*(tend-t0)), tdir, f0
33+
end
34+
35+
36+
A(λ) = [λ[1] 0 0 ; 0 λ[2] 0 ; 0 0 λ[1]-λ[2]]
37+
fun1(t,x) = A(λ)*x
38+
39+
fun2(t,xX) = [fun1(xX[:,1],λ,t) fun1(xX[:,2:end],λ,t)+[xX[1,1] 0 ; 0 xX[2,1] ; xX[3,1] xX[3,1]] ]
40+
41+
t0 = 0. ; tend = 2.;
42+
p = 2
43+
x0 = [0.,1.,1]
44+
reltol = 1.e-4; abstol = 1.e-4
45+
46+
hinit(fun1, x0, t0, tend, p, reltol, abstol)
47+
48+
xX0 = [funx0(λ) [0 1 ; 0 0 ; 0 0]]
49+
hinit(fun2, xX0, t0, tend, p, reltol, abstol)
50+
RelTol = reltol*ones(n,p+1)
51+
AbsTol = RelTol
52+
53+
hinit(fun2, xX0, t0, tend, p, RelTol, AbsTol)
54+
55+
RelTol = [reltol*ones(n,1) Inf*ones(n,p)]/sqrt(p+1)
56+
AbsTol = [abstol*ones(n,1) Inf*ones(n,p)]/sqrt(p+1)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using OrdinaryDiffEq, Test, DiffEqDevTools,
2+
ODEInterface, ODEInterfaceDiffEq
3+
4+
import ODEProblemLibrary: prob_ode_2Dlinear, prob_ode_linear
5+
6+
prob = prob_ode_linear
7+
#=
8+
prob.tspan
9+
prob.f
10+
prob.u0
11+
prob.p
12+
prob.kwargs
13+
prob.problem_type
14+
=#
15+
16+
sol = solve(prob, DP5())
17+
18+
sol2 = solve(prob, dopri5())
19+
println("sol.t[2] - sol2.t[2] = ", sol.t[2] - sol2.t[2])
20+
@test sol.t[2] sol2.t[2]
21+
22+
prob = prob_ode_2Dlinear
23+
sol = solve(prob, DP5(), internalnorm = (u, t) -> sqrt(sum(abs2, u)))
24+
25+
# Change the norm due to error in dopri5.f
26+
sol2 = solve(prob, dopri5())
27+
println("sol.t[2] - sol2.t[2] = ", sol.t[2] - sol2.t[2])
28+
@test sol.t[2] sol2.t[2]
29+
30+
prob = deepcopy(prob_ode_linear)
31+
prob
32+
#prob2 = ODEProblem(prob.f, prob.u0, (1.0, 0.0), 1.01)
33+
prob2 = ODEProblem(prob.f, prob.u0, (0.0, 1.0), 1.01)
34+
sol = solve(prob2, DP5())
35+
36+
sol2 = solve(prob2, dopri5())
37+
println("sol.t[2] - sol2.t[2] = ", sol.t[2] - sol2.t[2])
38+
@test sol.t[2] sol2.t[2]
39+
40+
prob = deepcopy(prob_ode_2Dlinear)
41+
#prob2 = ODEProblem(prob.f, prob.u0, (1.0, 0.0), 1.01)
42+
prob2 = ODEProblem(prob.f, prob.u0, (0.0, 1.0), 1.01)
43+
sol = solve(prob2, DP5(), internalnorm = (u, t) -> norm(u)/sqrt(length(u)))#sqrt(sum(abs2, u)))
44+
45+
# Change the norm due to error in dopri5.f
46+
sol2 = solve(prob2, dopri5())
47+
println("sol.t[2] - sol2.t[2] = ", sol.t[2] - sol2.t[2])
48+
@test sol.t[2] sol2.t[2]

article/figures/test_myode43.jl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
include("../../src/myode43/myode43.jl")
2+
3+
4+
# ẋ = [λ₁x₁ ; λ₂x₂ ; (λ₁-λ₂)x₃
5+
# x(t0) = x₀(λ) = [λ₂, 1, 1]
6+
# x(t,t0,x_0(λ),λ) = diag(exp(λ₁t),exp(λ₂t),exp((λ₁-λ₂)t))x₀(λ)
7+
# (∂x(t,t0,x_0(λ),λ)/∂x0) = diag(exp(λ₁t),exp(λ₂t),exp((λ₁-λ₂)t))
8+
# ∂x(t,t0,x_0(λ),λ)/∂λ = [λ₂texp(λ₁t) exp(λ₁t) ; 0 texp(λ₂t) ; texp((λ₁-λ₂)t)) -texp((λ₁-λ₂)t))]
9+
#
10+
# ∂x0_flow
11+
12+
A(λ) = [λ[1] 0 0 ; 0 λ[2] 0 ; 0 0 λ[1]-λ[2]]
13+
fun1(x,λ,t) = A(λ)*x
14+
15+
fun2(xX,λ,t) = [fun1(xX[:,1],λ,t) fun1(xX[:,2:end],λ,t)+[xX[1,1] 0 ; 0 xX[2,1] ; xX[3,1] xX[3,1]] ]
16+
17+
18+
19+
t0 = 0. ; tf = 2.; tspan = (t0,tf);
20+
λ = [1.,2]; p = length(λ);
21+
funx0(λ) = [λ[2],1.,1];
22+
x0 = funx0(λ)
23+
n = length(x0)
24+
reltol = 1.e-4; abstol = 1.e-4
25+
myode43(fun1,x0,λ,tspan,reltol,abstol)
26+
27+
xX0 = [x0 [0 1 ; 0 0 ; 0 0]]
28+
29+
myode43(fun2,xX0,λ,tspan,reltol,abstol)
30+
31+
RelTol = reltol*ones(n,p+1)
32+
AbsTol = RelTol
33+
34+
myode43(fun2,xX0,λ,tspan,RelTol,AbsTol)
35+
36+
RelTol = [reltol*ones(n,1) Inf*ones(n,p)]/sqrt(p+1)
37+
AbsTol = [abstol*ones(n,1) Inf*ones(n,p)]/sqrt(p+1)
38+
39+
inith(fun1,x0,λ,t0,abstol,reltol)
40+
41+
inith(fun2,xX0,λ,t0,abstol,reltol)
42+
RelTol = reltol*ones(n,p+1)
43+
AbsTol = RelTol
44+
inith(fun2,xX0,λ,t0,AbsTol,RelTol)
45+
46+
47+
epsi = eps()
48+
epsi = 0
49+
xX0 = [x0 [epsi 1 ; epsi epsi ; epsi epsi]]
50+
my_Inf = prevfloat(typemax(Float64))
51+
#my_Inf = Inf
52+
RelTol = [reltol*ones(n,1) my_Inf*ones(n,p)]/sqrt(p+1)
53+
AbsTol = [abstol*ones(n,1) my_Inf*ones(n,p)]/sqrt(p+1)
54+
inith(fun2,xX0,λ,t0,AbsTol,RelTol)
55+
myode43(fun2,xX0,λ,tspan,RelTol,AbsTol)
56+

article/figures/test_zygote.jl

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using OrdinaryDiffEq
2+
using LinearAlgebra
3+
using Plots
4+
using LaTeXStrings
5+
using ForwardDiff: ForwardDiff
6+
using Zygote: Zygote
7+
#using Mooncake # plante à l'instalation
8+
using SciMLSensitivity
9+
using DifferentiationInterface
10+
using DataFrames
11+
12+
include("../../src/CTDiffFlow.jl")
13+
using .CTDiffFlow
14+
include("../../src/myode43/myode43.jl")
15+
16+
function my_euler(fun,t0,x0,tf,λ,N)
17+
ti = t0; xi = x0
18+
h = (tf-t0)/N
19+
for i in 1:N
20+
xi += h*fun(xi,λ,ti)
21+
ti = ti+h
22+
end
23+
return xi
24+
end
25+
26+
27+
# Definition of the edo
28+
A(λ) = [λ[1] 0 0 ; 0 λ[2] 0 ; 0 0 λ[1]-λ[2]]
29+
fun1(x,λ,t) = A(λ)*x
30+
funx0(λ) = [λ[2],1.,1];
31+
N = 10
32+
t0 = 0. ; tf = 1.; tspan = (t0,tf);
33+
λ = [1.,2];
34+
reltol = 1.e-8
35+
abstol = reltol
36+
# ∂λ_flow(λ)
37+
sol_∂λ_flow = [λ[2]*exp(λ[1]*tf) exp(λ[1]*tf)
38+
0. tf*exp(λ[2]*tf)
39+
tf*exp((λ[1]-λ[2])*tf) -tf*exp((λ[1]-λ[2])*tf)]
40+
41+
42+
#dict_Zygote = Dict(:∂λ_sol => sol_∂λ_flow)
43+
#dict_ForwardDiff = Dict(:∂λ_sol => sol_∂λ_flow)
44+
45+
df = DataFrame(AutoDiff = String[], algo=String[], Jacobian = Matrix{<:Real}[])
46+
push!(df, ("solution", "", sol_∂λ_flow))
47+
48+
# Zygote with my_euler
49+
_flow(λ) = my_euler(fun1,t0,funx0(λ),tf,λ,N)
50+
#dict_Zygote[:my_euler] = jacobian(_flow,AutoZygote(),λ)
51+
#dict_ForwardDiff[:my_euler] = jacobian(_flow,AutoForwardDiff(),λ)
52+
push!(df, ("Zygote", "my-euler", jacobian(_flow,AutoZygote(),λ)))
53+
push!(df, ("ForwardDiff", "my-euler", jacobian(_flow,AutoForwardDiff(),λ)))
54+
# Zygote with numerical integration
55+
function _flow_int(λ)
56+
ivp = ODEProblem(fun1, funx0(λ), (t0,tf), λ)
57+
#algo = get(ode_kwargs, :alg, Tsit5())
58+
#println("algo = ", algo)
59+
60+
sol = solve(ivp, alg = Euler(),reltol=reltol,abstol=abstol,adaptive=false, dt = (tf-t0)/N)
61+
return sol.u[end]
62+
end
63+
64+
#dict_Zygote[:Euler] = jacobian(_flow_int,AutoZygote(),λ)
65+
#dict_ForwardDiff[:Euler] = jacobian(_flow_int,AutoForwardDiff(),λ)
66+
push!(df, ("Zygote", "Euler", jacobian(_flow_int,AutoZygote(),λ)))
67+
push!(df, ("ForwardDiff", "Euler", jacobian(_flow_int,AutoForwardDiff(),λ)))
68+
# Zygote with ∂λ_flow
69+
∂λ_flow = CTDiffFlow.build_∂λ_flow(fun1,t0,funx0,tf,λ; backend=AutoZygote())
70+
#dict_Zygote[:CTDiffFlowZygoteEuler] = ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol, alg = Euler(),adaptive=false, dt = (tf-t0)/N)#,print_times=false)
71+
push!(df, ("Zygote", "CTDiffFlow-Euler", ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol, alg = Euler(),adaptive=false, dt = (tf-t0)/N)))
72+
73+
# ForwardDiff with ∂λ_flow
74+
∂λ_flow = CTDiffFlow.build_∂λ_flow(fun1,t0,funx0,tf,λ; backend=AutoForwardDiff())
75+
#dict_ForwardDiff[:CTDiffFlowForwardDiffEuler] = ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol, alg = Euler(),adaptive=false, dt = (tf-t0)/N)#,print_times=false)
76+
push!(df, ("ForwardDiff", "my-euler", ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol, alg = Euler(),adaptive=false, dt = (tf-t0)/N)))
77+
78+
function _flow(λ)
79+
T, X = myode43(fun1,funx0(λ),λ,(t0,tf),abstol,reltol)
80+
return X[end]
81+
end
82+
83+
#dict_Zygote[:myode43Zygote] = jacobian(_flow,AutoZygote(),λ)
84+
#dict_ForwardDiff[:myode43ForwardDiff] = jacobian(_flow,AutoForwardDiff(),λ)
85+
push!(df, ("Zygote", "my-ode43", [NaN;;]))
86+
push!(df, ("ForwardDiff", "my-ode43", jacobian(_flow,AutoForwardDiff(),λ)))
87+
88+
jacobian(_flow,AutoForwardDiff(),λ)
89+
90+
latexify(df,arraystyle=:pmatrix,env=:tabular)
91+
92+
sol_Zygote = df[in.(df.AutoDiff, Ref(["solution","Zygote"])),:]
93+
sol_ForwardDiff = df[in.(df.AutoDiff, Ref(["solution", "ForwardDiff"])),:]
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
using Pkg
3+
Pkg.activate(".")
4+
using OrdinaryDiffEq
5+
using LinearAlgebra
6+
using Plots
7+
using LaTeXStrings
8+
using ForwardDiff: ForwardDiff
9+
using Zygote: Zygote
10+
#using Mooncake # plante à l'instalation
11+
using SciMLSensitivity
12+
using DifferentiationInterface
13+
14+
include("../../src/CTDiffFlow.jl")
15+
using .CTDiffFlow
16+
#
17+
# Definition of the second member
18+
function bruss(x,par,t)
19+
λ = par[1]
20+
x₁ = x[1]
21+
x₂ = x[2]
22+
return [1+x₁^2*x₂-+1)*x₁ , λ*x₁-x₁^2*x₂]
23+
end
24+
25+
t0 = 0.; tf = 1.
26+
tspan = (t0,tf)
27+
λ = [3.]
28+
p = length(λ)
29+
x01 = 1.3
30+
funx0(λ) = [x01, λ[1]]
31+
tol = 1.e-4
32+
n = 2
33+
34+
plt1 = plot(); plt2 = plot()
35+
algo = Tsit5()
36+
reltol = 1.e-4; abstol = 1.e-4
37+
38+
# Flow
39+
ivp = ODEProblem(bruss, funx0(λ), (t0,tf), λ)
40+
sol_ivp = solve(ivp, alg=algo; reltol=reltol,abstol=abstol)
41+
println("Flow")
42+
println("Times for the initial flow T = ")
43+
println(sol_ivp.t)
44+
dict_T = Dict(:ivp => sol_ivp.t)
45+
dt = sol_ivp.t[2]
46+
47+
# -------------------------------
48+
println("Vatiational equation")
49+
# ------------------------------
50+
51+
∂λ_flow_var = CTDiffFlow.build_∂λ_flow_var(bruss,t0,funx0,tf,λ)
52+
53+
#println(∂λ_flow_var(t0,funx0,tf,λ;reltol=reltol,abstol=abstol))
54+
sol_var = ∂λ_flow_var((t0,tf),funx0,λ;reltol=reltol,abstol=abstol)
55+
sol_var = ∂λ_flow_var((t0,tf),funx0,λ;reltol=reltol,abstol=abstol,internalnorm = (u,t)->norm(u))
56+
println("Times default values= ", sol_var.t)
57+
dict_T[:var_reltol] = sol_var.t
58+
my_Inf = prevfloat(typemax(Float64))
59+
RelTol = [reltol*ones(n,1) Inf*ones(n,1)]/sqrt(p+1)
60+
AbsTol = [abstol*ones(n,1) Inf*ones(n,1)]/sqrt(p+1)
61+
sol_var = ∂λ_flow_var((t0,tf),funx0,λ;reltol=RelTol,abstol=AbsTol)
62+
sol_var = ∂λ_flow_var((t0,tf),funx0,λ;reltol=RelTol,abstol=AbsTol, dt=dt)#,internalnorm = (u,t)->norm(u) )
63+
println("RelTol = ", RelTol)
64+
println("Times = ", sol_var.t)
65+
println(sol_ivp.t - sol_var.t)
66+
dict_T[:var_RelTol] = sol_var.t
67+
68+
# ne fonctionne pas
69+
#@btime ∂λ_flow_var(t0,funx0,tf,λ;reltol=reltol,abstol=abstol)
70+
71+
println("Automatic differentiation")
72+
println("with ForwardDiff")
73+
∂λ_flow = CTDiffFlow.build_∂λ_flow(bruss,t0,funx0,tf,λ)
74+
sol_diff_auto_flow, T = ∂λ_flow(t0,funx0,tf,λ;reltol=RelTol,abstol=AbsTol,print_times=true)
75+
println("Times : ", T)
76+
dict_T[:diff_auto_ForwardDiff] = T
77+
#sol_diff_auto_flow, T = ∂λ_flow(tspan,funx0,λ;reltol=RelTol,abstol=AbsTol,print_times=true)
78+
#=
79+
println("internalnorm = (u,t)->norm(u)")
80+
println(∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol,internalnorm = (u,t)->norm(u),print_times=true))
81+
#@btime ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol)
82+
=#
83+
println("With Zygote")
84+
# with Zygote
85+
∂λ_flow = CTDiffFlow.build_∂λ_flow(bruss,t0,funx0,tf,λ; backend=AutoZygote())
86+
sol_diff_auto_flow_tf, T = ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol,print_times=true)
87+
dict_T[:diff_auto_Zygote] = T
88+
println(sol_diff_auto_flow_tf-sol_var)
89+
#sol_diff_auto_flow,T = ∂λ_flow(tspan,funx0,λ;reltol=reltol,abstol=abstol,print_times=true)
90+
#println(sol_diff_auto_flow)
91+
#reshape(sol_diff_auto_flow,2,7)
92+
93+
#@btime ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol)
94+
95+
println("With Mooncake")
96+
# plante
97+
#∂λ_flow = CTDiffFlow.build_∂λ_flow(bruss,t0,funx0,tf,λ; backend=AutoMooncake())
98+
#println(∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol,print_times=true))
99+
#@btime ∂λ_flow(t0,funx0,tf,λ;reltol=reltol,abstol=abstol)
100+
101+
#plot(plt1,plt2)
102+

0 commit comments

Comments
 (0)