Skip to content

Commit 81b4df5

Browse files
committed
Update McCormick support and test support
1 parent a4e337c commit 81b4df5

5 files changed

Lines changed: 49 additions & 215 deletions

File tree

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2222
Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4"
2323

2424
[compat]
25-
DataStructures = "0.17.11"
25+
DataStructures = "~0.17, ~0.18"
2626
DiffEqBase = "~5, ~6"
27-
DiffEqSensitivity = "~5, ~6"
27+
DiffEqSensitivity = "~6"
2828
DiffResults = "~0.0, ~1.0"
2929
DocStringExtensions = "~0.8"
3030
DynamicBoundsBase = "0.5.3"
3131
ElasticArrays = "~1"
3232
ForwardDiff = "~0.10"
33-
McCormick = "~0.7, ~0.8, ~0.9, ~0.10"
33+
McCormick = "~0.7, ~0.8, ~0.9, ~0.10, ~0.11"
3434
Polynomials = "~1.2"
3535
Requires = "1.0"
3636
Reexport = "~0.2"

example/example.jl

Lines changed: 6 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ println(" ------------------------------------------------------------ ")
4141
use_relax = false
4242
lohners_type = 2
4343
prob_num = 1
44-
ticks = 100.0
45-
steps = 100.0
46-
tend = 1*steps/ticks # lo 7.6100
44+
ticks = 50.0
45+
steps = 50.0
46+
tend = 0.02*steps/ticks # lo 7.6100
4747

4848
if prob_num == 1
4949
x0(p) = [9.0]
5050
function f!(dx, x, p, t)
51-
dx[1] = p[1] - x[1]*x[1]
51+
dx[1] = p[1] - x[1]^2 #x[1]*x[1]
5252
nothing
5353
end
5454
tspan = (0.0, tend)
@@ -72,7 +72,7 @@ tol = 1E-5
7272

7373
if lohners_type == 1
7474
integrator = DiscretizeRelax(prob, DynamicBoundspODEsDiscrete.LohnerContractor{5}(), h = 1/ticks,
75-
repeat_limit = 1, skip_step2 = false, step_limit = steps, relax = false, tol= tol)
75+
repeat_limit = 1, skip_step2 = false, step_limit = steps, relax = use_relax, tol= tol)
7676
elseif lohners_type == 2
7777
integrator = DiscretizeRelax(prob, DynamicBoundspODEsDiscrete.HermiteObreschkoff(3, 3), h = 1/ticks,
7878
repeat_limit = 1, skip_step2 = false, step_limit = steps, relax = use_relax, tol= tol)
@@ -90,58 +90,10 @@ elseif lohners_type == 3
9090
relax = false, Jx! = iJx!, Jp! = iJp!, tol= tol)
9191
end
9292

93-
#=
94-
integrator = DiscretizeRelax(prob, DynamicBoundspODEsDiscrete.AdamsMoulton(4), h = 0.01,
95-
repeat_limit = 1, skip_step2 = false, step_limit = 3, relax = use_relax)
96-
97-
integrator = DiscretizeRelax(prob, DynamicBoundspODEsDiscrete.HermiteObreschkoff(3, 3), h = 0.01,
98-
repeat_limit = 1, skip_step2 = false, step_limit = 5, relax = use_relax)
99-
=#
100-
#=
101-
function iJx!(dx, x, p, t)
102-
dx[1] = -2.0*x[1]
103-
nothing
104-
end
105-
function iJp!(dx, x, p, t)
106-
dx[1] = one(p[1])
107-
nothing
108-
end
109-
integrator = DiscretizeRelax(prob, PLMS(4, AdamsMoulton()), h = 0.01, skip_step2 = false, relax = false, Jx! = iJx!, Jp! = iJp!)
110-
=#
111-
11293
ratio = rand(1)
11394
pstar = pL.*ratio .+ pU.*(1.0 .- ratio)
11495
setall!(integrator, ParameterValue(), [0.0])
11596
DynamicBoundsBase.relax!(integrator)
116-
117-
#ratio = rand(1)
118-
#pstar = pL.*ratio .+ pU.*(1.0 .- ratio)
119-
#setall!(integrator, ParameterValue(), [0.0])
120-
#DynamicBoundsBase.relax!(integrator)
121-
122-
#println("alloc_num: $(alloc_num)")
123-
124-
125-
#function relax_test()
126-
# ratio = rand(1)
127-
# pstar = pL.*ratio .+ pU.*(1.0 .- ratio)
128-
# setall!(integrator, ParameterValue(), [0.0])
129-
# DynamicBoundsBase.relax!(integrator)
130-
# return nothing
131-
#end
132-
#@btime relax_test()
133-
134-
d = integrator
135-
136-
#@code_warntype DynamicBoundspODEsPILMS.single_step!(d.step_result, d.step_params, d.method_f!, d.set_tf!, d.Δ, d.A, d.P, d.rP, d.p)
137-
#=
138-
method_f! = d.method_f!
139-
@code_warntype method_f!(d.step_result.steps, d.step_result.times, d.step_result.unique_result.X, d.step_result.Xⱼ,
140-
d.step_result.xⱼ, d.A, d.Δ, d.P, d.rP, d.p, d.step_result.unique_result.fk)
141-
=#
142-
#using BenchmarkTools
143-
#@btime DynamicBoundsBase.relax!($integrator)
144-
14597
integrate!(integrator)
14698

14799
t_vec = integrator.time
@@ -151,27 +103,11 @@ if !use_relax
151103
else
152104
lo_vec = getfield.(getfield.(getindex.(integrator.storage[:],1), :Intv), :lo)
153105
hi_vec = getfield.(getfield.(getindex.(integrator.storage[:],1), :Intv), :hi)
154-
#lo_vec = getfield.(getindex.(integrator.storage[:],1), :cv)
155-
#hi_vec = getfield.(getindex.(integrator.storage[:],1), :cc)
156106
end
157107

158108
plt = plot(t_vec , lo_vec, label="Interval Bounds 0.0", marker = (:hexagon, 2, 0.6, :green), linealpha = 0.0, legend=:bottomleft)
159109
plot!(plt, t_vec , hi_vec, label="", linealpha = 0.0, marker = (:hexagon, 2, 0.6, :green))
160-
#=
161-
prob = DynamicBoundsBase.ODERelaxProb(f!, tspan, x0, pL, pU)
162-
integrator = DiscretizeRelax(prob, h = 0.01, skip_step2 = false, k = kval)
163-
ratio = rand(1)
164-
pstar = pL.*ratio .+ pU.*(1.0 .- ratio)
165-
setall!(integrator, ParameterValue(), [1.0])
166-
DynamicBoundsBase.relax!(integrator)
167110

168-
t_vec = integrator.time
169-
lo_vec = getfield.(getindex.(integrator.storage[:],1), :lo)
170-
hi_vec = getfield.(getindex.(integrator.storage[:],1), :hi)
171-
plot!(plt, t_vec , lo_vec, label="Interval Bounds 1.0", linecolor = :green, linestyle = :dash,
172-
lw=1.5, legend=:bottomleft)
173-
plot!(plt, t_vec , hi_vec, label="", linecolor = :green, linestyle = :dash, lw=1.5)
174-
=#
175111
prob = ODEProblem(f!, [9.0], tspan, [-1.0])
176112
sol = solve(prob, Tsit5(), reltol=1e-8, abstol=1e-8)
177113
plot!(plt, sol.t , sol[1,:], label="", linecolor = :red, linestyle = :solid, lw=1.5)
@@ -182,116 +118,4 @@ plot!(plt, sol.t , sol[1,:], label="", linecolor = :red, linestyle = :solid, lw=
182118

183119
ylabel!("x[1] (M)")
184120
xlabel!("Time (seconds)")
185-
display(plt)
186-
187-
status_code = get(integrator, TerminationStatus())
188-
println("status code: $(status_code)")
189-
d = integrator
190-
t = 2.3
191-
192-
#@code_warntype DynamicBoundspODEsPILMS.single_step!(d.step_result, d.step_params, d.method_f!, d.set_tf!, d.Δ, d.A, d.P, d.rP, d.p, t)
193-
#@btime DynamicBoundspODEsPILMS.single_step!($(d.step_result), $(d.step_params), $(d.method_f!),
194-
# $(d.set_tf!), $(d.Δ), $(d.A), $(d.P), $(d.rP), $(d.p), $t)
195-
196-
197-
#println("INTERNAL TESTS 1!")
198-
#=
199-
@code_warntype DynamicBoundspODEsPILMS.existence_uniqueness!(integrator.step_result,
200-
integrator.set_tf!,
201-
integrator.step_params.hmin,
202-
integrator.P,
203-
t)
204-
=#
205-
#=
206-
println("INTERNAL TESTS 2!")
207-
out = d.step_result
208-
lf = integrator.method_f!
209-
=#
210-
#=
211-
@code_warntype lf(out.hj, out.unique_result.X, out.Xⱼ, out.xⱼ, d.A, d.Δ,
212-
d.P, d.rP, d.p, t)
213-
=#
214-
#=
215-
hj = out.hj
216-
urX = out.unique_result.X
217-
Xⱼ = out.Xⱼ
218-
xⱼ = out.xⱼ
219-
A = d.A
220-
del = d.Δ
221-
P = d.P
222-
rP = d.rP
223-
p = d.p
224-
=#
225-
#@btime ($lf)($hj, $urX, $Xⱼ, $xⱼ, $A, $del, $P, $rP, $p, $t)
226-
227-
#println("INTERNAL TESTS 3!")
228-
#jacfunc = lf.jac_tf!
229-
#@code_warntype DynamicBoundspODEsPILMS.set_JxJp!(jacfunc, out.Xⱼ, d.P, t)
230-
#@btime DynamicBoundspODEsPILMS.set_JxJp!($jacfunc, $(out.Xⱼ), $(d.P), $t)
231-
232-
#@code_warntype DynamicBoundspODEsPILMS.jacobian_taylor_coeffs!(jacfunc, out.Xⱼ, d.P, t)
233-
#@btime DynamicBoundspODEsPILMS.jacobian_taylor_coeffs!($jacfunc, $(out.Xⱼ), $(d.P), $t)
234-
#=
235-
r = jacfunc.result
236-
aot = jacfunc.out
237-
yot = jacfunc.y
238-
cfg = jacfunc.cfg
239-
240-
println(" ")
241-
println(" ")
242-
println("jacobian stuff")
243-
=#
244-
#@code_warntype ForwardDiff.jacobian!(r, jacfunc, aot, yot, compare_config)
245-
#@btime ForwardDiff.jacobian!($r, $jacfunc, $aot, $yot, $compare_config)
246-
247-
#println(" ")
248-
#println(" ")
249-
#println("jacobian functor stuff")
250-
#outy = [integrator.method_f!.jac_tf!.x[1] for i in 1:21]
251-
#iny = [integrator.method_f!.jac_tf!.x[1], integrator.method_f!.jac_tf!.p[1]]
252-
#@code_warntype jacfunc(outy, iny)
253-
#@btime ($jacfunc)($outy, $iny)
254-
255-
#=
256-
order = 20
257-
val = Val(21-1)
258-
xtaylor = [STaylor1(integrator.method_f!.jac_tf!.x[1], val)]
259-
xaux = deepcopy(xtaylor)
260-
dx = deepcopy(xtaylor)
261-
eqdiffs = jacfunc.g!
262-
P = integrator.method_f!.jac_tf!.p[1]
263-
println("jetcoeffs stuff")
264-
vnxt = fill(0, 1)
265-
fnxt = fill(0.0, 1)
266-
=#
267-
#@code_warntype DynamicBoundspODEsPILMS.jetcoeffs!(eqdiffs, t, xtaylor, xaux, dx, order, P, vnxt, fnxt)
268-
#@btime DynamicBoundspODEsPILMS.jetcoeffs!($eqdiffs, $t, $xtaylor, $xaux, $dx, $order, $P, $vnxt, $fnxt)
269-
270-
#println("recurse taylor")
271-
#@code_warntype DynamicBoundspODEsPILMS.recurse_taylor!(dx, xtaylor, vnxt)
272-
#@btime DynamicBoundspODEsPILMS.recurse_taylor!($dx, $xtaylor, $vnxt)
273-
274-
println(" copy recurse")
275-
#sdx = dx[1]
276-
#sxtaylor = xtaylor[1]
277-
#cflt = 1.0
278-
# @code_warntype DynamicBoundspODEsPILMS.copy_recurse(sdx, sxtaylor, 1, cflt)
279-
# @btime DynamicBoundspODEsPILMS.copy_recurse($sdx, $sxtaylor, 1, $cflt)
280-
#=
281-
s = integrator.step_result
282-
@code_warntype DynamicBoundspODEsPILMS.existence_uniqueness!(s.unique_result, integrator.set_tf!, s.Xⱼ, s.hj,
283-
integrator.step_params.hmin, s.f, s.∂f∂x,
284-
s.∂f∂p, integrator.P, s.h, t)
285-
=#
286-
#=
287-
ratio = rand(6)
288-
pstar = pL.*ratio .+ pU.*(1.0 .- ratio)
289-
setall!(integrator, ParameterValue(), pstar)
290-
integrate!(integrator)
291-
plot!(plt, integrator.local_problem_storage.integrator_t,
292-
integrator.local_problem_storage.pode_x[1,:], label="Trajectories", linecolor = :green,
293-
markershape = :+, markercolor = :green, linestyle = :dash, markersize = 2, lw=0.75)
294-
=#
295-
296-
297-
# seed!(xdual, x, cfg.seeds)
121+
display(plt)

src/DiscretizeRelax/method/hermite_obreschkoff.jl

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -247,16 +247,16 @@ function _pred_compute_rhs_jacobian!(d, c::ContractorStorage{S}, t) where S
247247
ρ!(d.ρP, c.P, c.pval, d.η)
248248
set_JxJp!(Jf!_pred, d.μX, d.ρP, t)
249249
for i = 1:d.q_predict
250-
hji1 = hⱼ^(i-1)
250+
hji1 = hⱼ^i
251251
if i == 1
252252
fill!(Jf!_pred.Jxsto, zero(S))
253253
for j = 1:d.nx
254254
Jf!_pred.Jxsto[j,j] = one(S)
255255
end
256256
else
257-
@__dot__ Jf!_pred.Jxsto += hji1*Jf!_pred.Jx[i]
257+
@__dot__ Jf!_pred.Jxsto += hji1*Jf!_pred.Jx[i+1]
258258
end
259-
@__dot__ Jf!_pred.Jpsto += hji1*Jf!_pred.Jp[i]
259+
@__dot__ Jf!_pred.Jpsto += hji1*Jf!_pred.Jp[i+1]
260260
end
261261
return nothing
262262
end
@@ -272,6 +272,7 @@ function _hermite_obreschkoff_predictor!(d::HermiteObreschkoffFunctor{F,P1,Q1,K,
272272
mul_split!(d.pred_Jxvec, d.pred_Jxmat, c.Δ[2], d.nx)
273273
mul_split!(d.pred_Jpvec, d.Jf!_pred.Jpsto, c.rP, d.nx)
274274
@__dot__ d.X_predict = d.Vⱼ₊₁ + d.Rⱼ₊₁ + d.pred_Jxvec + d.pred_Jpvec
275+
275276
return nothing
276277
end
277278

@@ -281,37 +282,40 @@ function (d::HermiteObreschkoffFunctor{F,P1,Q1,K,T,S,NY})(contract::ContractorSt
281282

282283
_hermite_obreschkoff_predictor!(d, contract)
283284

284-
map!(mid, d.xval_correct, d.X_predict)
285+
map!(mid, d.xval_correct, d.X_predict) # GOOD
285286

286287
# extract method constants
287288
ho = d.hermite_obreschkoff
288289
γ = ho.γ
289-
p = ho.p
290-
q = ho.q
291-
k = ho.k
292-
nx = d.nx
293-
np = length(contract.pval)
290+
p = ho.p # GOOD
291+
q = ho.q # GOOD
292+
k = ho.k # GOOD
293+
nx = d.nx # GOOD
294+
np = length(contract.pval) # GOOD
294295

295-
hⱼ = contract.hj_computed
296-
t = contract.times[1]
297-
hjk = hⱼ^k
298-
_sum_pred(y, i) = y[i]*ho.cpq[i]*hⱼ^(i - 1)
299-
_sum_q(y, i) = (ho.cqp[i]*(-hⱼ)^(i-1))*y[i]
296+
hⱼ = contract.hj_computed # GOOD
297+
t = contract.times[1] # GOOD
298+
hjk = hⱼ^k # GOOD
299+
_sum_pred(y, i) = y[i+1]*ho.cpq[i+1]*hⱼ^(i)
300+
_sum_q(y, i) = (ho.cqp[i+1]*(-hⱼ)^i)*y[i+1]
300301

301-
d.sum_p .= mapreduce(i -> _sum_pred(d.f̃val_pred, i), +, 1:(p + 1))
302+
d.sum_p .= mapreduce(i -> _sum_pred(d.f̃val_pred, i), +, 1:p)
302303

303304
d.real_tf!_correct(d.f̃val_correct, d.xval_correct, contract.pval, t)
304-
d.sum_q .= mapreduce(i -> _sum_q(d.f̃val_correct, i), +, 1:(q + 1))
305-
@__dot__ d.δⱼ₊₁ = d.sum_p - d.sum_q + γ*hjk*d.f̃_pred[k + 1]
305+
d.sum_q .= mapreduce(i -> _sum_q(d.f̃val_correct, i), +, 1:q)
306+
307+
@__dot__ d.δⱼ₊₁ = contract.xval - d.xval_correct + d.sum_p - d.sum_q + γ*hjk*d.f̃_pred[k + 1] # Looks wrong based on impact....
306308

307-
d.Jf!_pred.Jxsto .= mapreduce(i -> _sum_pred(d.Jf!_pred.Jx, i), +, 1:(p + 1))
308-
d.Jf!_pred.Jpsto .= mapreduce(i -> _sum_pred(d.Jf!_pred.Jp, i), +, 1:(p + 1))
309+
d.Jf!_pred.Jxsto .= mapreduce(i -> _sum_pred(d.Jf!_pred.Jx, i), +, 1:p)
310+
d.Jf!_pred.Jpsto .= mapreduce(i -> _sum_pred(d.Jf!_pred.Jp, i), +, 1:p)
311+
d.Jf!_pred.Jxsto += d.Inx
309312

310313
μ!(d.μX, d.X_predict, d.xval_correct, d.η)
311314
ρ!(d.ρP, contract.P, contract.pval, d.η)
312315
set_JxJp!(d.Jf!_correct, d.μX, d.ρP, t)
313-
d.Jf!_correct.Jxsto .= mapreduce(i -> _sum_q(d.Jf!_correct.Jx, i), +, 1:(q + 1))
314-
d.Jf!_correct.Jpsto .= mapreduce(i -> _sum_q(d.Jf!_correct.Jp, i), +, 1:(q + 1))
316+
d.Jf!_correct.Jxsto .= mapreduce(i -> _sum_q(d.Jf!_correct.Jx, i), +, 1:q)
317+
d.Jf!_correct.Jpsto .= mapreduce(i -> _sum_q(d.Jf!_correct.Jp, i), +, 1:q)
318+
d.Jf!_correct.Jxsto += d.Inx
315319

316320
map!(mid, d.precond, d.Jf!_correct.Jxsto)
317321
lu!(d.precond)
@@ -332,11 +336,10 @@ function (d::HermiteObreschkoffFunctor{F,P1,Q1,K,T,S,NY})(contract::ContractorSt
332336
mul_split!(d.CprP, d.Cp, contract.rP, nx)
333337
mul_split!(d.Yδⱼ₊₁, d.precond, d.δⱼ₊₁, nx)
334338
@__dot__ contract.X_computed = d.xval_correct + d.correct_Bvec + d.Uj + d.CprP + d.Yδⱼ₊₁
339+
335340
@__dot__ contract.X_computed = contract.X_computed d.X_predict
336-
@show contract.X_computed
337-
@show d.X_predict
338-
affine_contract!(contract.X_computed, contract.P, contract.pval, nx, np)
339341

342+
affine_contract!(contract.X_computed, contract.P, contract.pval, nx, np)
340343
@__dot__ contract.xval_computed = mid(contract.X_computed)
341344

342345
# calculation block for computing Aⱼ₊₁ and inv(Aⱼ₊₁)

src/DiscretizeRelax/utilities/relax.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ function DBB.relax!(d::DiscretizeRelax{M,T,S,F,K,X,NY}) where {M <: AbstractStat
104104
copyto!(d.storage[step_number], d.contractor_result.X_computed)
105105
copyto!(d.storage_apriori[step_number], d.exist_result.Xj_apriori)
106106
d.time[step_number] = d.step_result.time
107+
d.contractor_result.times[1] = d.step_result.time
107108
end
108109
if is_support_pnt
109110
stored_value_count += 1

test/runtests.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,23 @@ if !(VERSION < v"1.1" && testfile == "intervals.jl")
277277
(^, t1, 3, t2, 3),
278278
(^, t1, 4, t2, 4),
279279
(/, 1.3, t1, 1.3, t2),
280-
(^, t1, -1, t2, -1),
281-
(^, t1, -2, t2, -2),
282-
(^, t1, -3, t2, -3),
280+
#(^, t1, -1, t2, -1),
281+
#(^, t1, -2, t2, -2),
282+
#(^, t1, -3, t2, -3),
283283
(^, t1, 0.6, t2, 0.6),
284284
(^, t1, 1 / 2, t2, 1 / 2),
285285
)
286286
temp1 = test_tup[1](test_tup[2], test_tup[3])
287287
temp2 = test_tup[1](test_tup[4], test_tup[5])
288-
@test isapprox(temp1[0], temp2[0], atol = 1E-10)
289-
@test isapprox(temp1[1], temp2[1], atol = 1E-10)
290-
@test isapprox(temp1[2], temp2[2], atol = 1E-10)
288+
check1 = isapprox(temp1[0], temp2[0], atol = 1E-10)
289+
check2 = isapprox(temp1[1], temp2[1], atol = 1E-10)
290+
check3 = isapprox(temp1[2], temp2[2], atol = 1E-10)
291+
@test check1
292+
@test check2
293+
@test check3
294+
if !check1 || !check2 || !check3
295+
println("$test_tup, $temp1, $temp2")
296+
end
291297
end
292298

293299
@test isapprox(

0 commit comments

Comments
 (0)