Skip to content

Commit a9c1eab

Browse files
committed
Add derivative contractors
1 parent 4099735 commit a9c1eab

File tree

1 file changed

+125
-1
lines changed

1 file changed

+125
-1
lines changed

src/optimise1.jl

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using IntervalArithmetic, DataStructures
1+
using IntervalRootFinding, IntervalArithmetic, StaticArrays, ForwardDiff, BenchmarkTools, Compat, IntervalOptimisation, DataStructures
22

33
import Base.isless
44

@@ -15,6 +15,83 @@ function minimise1d(f::Function, x::Interval{T}; reltol=1e-3, abstol=1e-3) where
1515

1616
Q = binary_minheap(IntervalMinima{T})
1717

18+
minima = f(interval(mid(x))).hi
19+
20+
arg_minima = Interval{T}[]
21+
22+
push!(Q, IntervalMinima(x, minima))
23+
24+
while !isempty(Q)
25+
26+
p = pop!(Q)
27+
28+
if isempty(p.intval)
29+
continue
30+
end
31+
32+
if p.minima > minima
33+
continue
34+
end
35+
36+
# deriv = ForwardDiff.derivative(f, p.intval)
37+
# if 0 ∉ deriv
38+
# continue
39+
# end
40+
41+
doublederiv = ForwardDiff.derivative(x->ForwardDiff.derivative(f, x), p.intval)
42+
if doublederiv < 0
43+
continue
44+
end
45+
46+
m = mid(p.intval)
47+
48+
current_minima = f(interval(m)).hi
49+
50+
if current_minima < minima
51+
minima = current_minima
52+
end
53+
54+
55+
# # Contractor 1
56+
# x = m .+ extended_div((interval(-∞, minima) - f(m)), deriv)
57+
#
58+
# x = x .∩ p.intval
59+
60+
# Contractor 2
61+
@show p.intval
62+
@show (doublederiv/2, ForwardDiff.derivative(f, interval(m)), f(m) - interval(-∞, minima))
63+
@show (m .+ quadratic_roots(doublederiv/2, ForwardDiff.derivative(f, interval(m)), f(m) - interval(-∞, minima)))
64+
x = m .+ quadratic_roots(doublederiv/2, ForwardDiff.derivative(f, interval(m)), f(m) - interval(-∞, minima))
65+
66+
x = x .∩ p.intval
67+
68+
if diam(p.intval) < abstol
69+
push!(arg_minima, p.intval)
70+
else
71+
if length(x) == 1
72+
x1, x2 = bisect(x[1])
73+
push!(Q, IntervalMinima(x1, f(x1).lo), IntervalMinima(x2, f(x2).lo))
74+
else
75+
push!(Q, IntervalMinima.(x, inf.(f.(x)))...)
76+
end
77+
# if isempty(x[2])
78+
# x1, x2 = bisect(x[1])
79+
# push!(Q, IntervalMinima(x1, f(x1).lo), IntervalMinima(x2, f(x2).lo))
80+
# else
81+
# x1, x2, x3 = x
82+
# push!(Q, IntervalMinima(x1, f(x1).lo), IntervalMinima(x2, f(x2).lo), IntervalMinima(x3, f(x3).lo))
83+
# end
84+
end
85+
end
86+
87+
return minima, arg_minima
88+
end
89+
90+
91+
function minimise1d_noderiv(f::Function, x::Interval{T}; reltol=1e-3, abstol=1e-3) where {T<:Real}
92+
93+
Q = binary_minheap(IntervalMinima{T})
94+
1895
minima = f(interval(mid(x))).hi
1996
arg_minima = Interval{T}[]
2097

@@ -50,3 +127,50 @@ function minimise1d(f::Function, x::Interval{T}; reltol=1e-3, abstol=1e-3) where
50127

51128
return minima, arg_minima
52129
end
130+
131+
132+
133+
struct IntervalBoxMinima{N, T<:Real}
134+
intval::IntervalBox{N, T}
135+
minima::T
136+
end
137+
138+
function isless(a::IntervalBoxMinima{N, T}, b::IntervalBoxMinima{N, T}) where {N, T<:Real}
139+
return isless(a.minima, b.minima)
140+
end
141+
142+
function minimisend(f::Function, x::IntervalBox{N, T}; reltol=1e-3, abstol=1e-3) where {N, T<:Real}
143+
144+
Q = binary_minheap(IntervalBoxMinima{N, T})
145+
146+
minima = f(x).lo
147+
arg_minima = IntervalBox{N, T}[]
148+
149+
push!(Q, IntervalBoxMinima(x, minima))
150+
151+
while !isempty(Q)
152+
153+
p = pop!(Q)
154+
155+
if p.minima > minima
156+
continue
157+
end
158+
159+
if 0 .∉ ForwardDiff.gradient(f, p.intval)
160+
continue
161+
end
162+
163+
if p.minima < minima
164+
minima = p.minima
165+
end
166+
167+
if diam(p.intval) < abstol
168+
push!(arg_minima, p.intval)
169+
else
170+
x1, x2 = bisect(p.intval)
171+
push!(Q, IntervalBoxMinima(x1, f(x1).lo), IntervalBoxMinima(x2, f(x2).lo))
172+
end
173+
end
174+
175+
return minima, arg_minima
176+
end

0 commit comments

Comments
 (0)