Skip to content

Commit 4e628ca

Browse files
committed
use LazySets plot recipes
1 parent 20cd943 commit 4e628ca

File tree

4 files changed

+21
-140
lines changed

4 files changed

+21
-140
lines changed

docs/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
99
LazySets = "b4f0291d-fe17-52bc-9479-3d1a343d9043"
1010
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
1111
MathematicalSystems = "d14a8603-c872-5ed3-9ece-53e0e82e39da"
12+
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
1213
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
1314
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1415
ReachabilityBase = "379f33d0-9447-4353-bd03-d664070e549f"
@@ -25,6 +26,7 @@ LaTeXStrings = "1"
2526
LazySets = "2.14, 3, 4, 5"
2627
Literate = "2"
2728
MathematicalSystems = "0.14.1"
29+
Optim = "0.15 - 0.22, 1"
2830
OrdinaryDiffEq = "6"
2931
Plots = "1"
3032
ReachabilityBase = "0.2.3 - 0.3"

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Documenter, ReachabilityAnalysis, DocumenterCitations
22

33
# load optional packages for complete documentation
4-
import ExponentialUtilities
4+
import ExponentialUtilities, Optim
55

66
DocMeta.setdocmeta!(ReachabilityAnalysis, :DocTestSetup,
77
:(using ReachabilityAnalysis); recursive=true)

docs/src/tutorials/linear_methods/discrete_time.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ To gain some intuition, let's build the matrix and apply it to some points.
2626
```@example discrete_propagation
2727
using ReachabilityAnalysis, Plots
2828
using ReachabilityAnalysis: center
29+
import Optim
2930
3031
# initial set
3132
X0 = BallInf(ones(2), 0.2)

src/Flowpipes/recipes.jl

Lines changed: 17 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ end
6565

6666
function _project_reachset(::Type{<:LazySet}, R, vars)
6767
πR = Projection(R, vars) # lazy projection
68-
return X = set(πR)
68+
return set(πR)
6969
end
7070

7171
# ---------------------------------------
@@ -128,9 +128,6 @@ end
128128
vars=nothing,
129129
ε=N(PLOT_PRECISION)) where {N}
130130
_check_vars(vars)
131-
X = _project_reachset(R, vars)
132-
133-
dim(X) == 1 && return plot_recipe(X, ε)
134131

135132
label --> DEFAULT_LABEL
136133
grid --> DEFAULT_GRID
@@ -140,121 +137,20 @@ end
140137
seriesalpha --> DEFAULT_ALPHA
141138
seriescolor --> DEFAULT_COLOR
142139

143-
# extract limits and extrema of already plotted sets
144-
p = plotattributes[:plot_object]
145-
lims = _extract_limits(p, plotattributes)
146-
extr = _extract_extrema(p)
147-
148-
if !isbounded(X)
149-
_set_auto_limits_to_extrema!(lims, extr)
150-
X = intersection(X, _bounding_hyperrectangle(lims, eltype(X)))
151-
152-
elseif length(p) > 0
153-
# if there is already a plotted set and the limits are fixed,
154-
# automatically adjust the axis limits (e.g. after plotting a unbounded set)
155-
_update_plot_limits!(lims, X)
156-
end
157-
158-
xlims --> lims[:x]
159-
ylims --> lims[:y]
160-
161-
x, y = plot_recipe(X, ε)
162-
if !isempty(x)
163-
m = length(x)
164-
if m == 1
165-
seriestype := :scatter
166-
elseif m == 2 && isapproxzero((x[1] - x[2])^2 + (y[1] - y[2])^2)
167-
seriestype := :scatter
168-
else
169-
seriestype := :shape
170-
end
171-
end
172-
return (x, y)
173-
end
174-
175-
# TODO use LazySets._plot_singleton_list_1D if the reach-sets are stored as a struct
176-
# array. Otherwise, we could use pass the list through x -> set(x)
177-
function _plot_singleton_list_1D(list::Union{Flowpipe{N},AbstractVector{<:AbstractReachSet{N}}}) where {N}
178-
m = length(list)
179-
180-
x = Vector{N}(undef, m)
181-
y = zeros(N, m)
182-
183-
@inbounds for (i, Xi) in enumerate(list)
184-
p = element(set(Xi))
185-
x[i] = p[1]
186-
end
187-
return x, y
188-
end
189-
190-
function _plot_singleton_list_2D(list::Union{Flowpipe{N},AbstractVector{<:AbstractReachSet{N}}}) where {N}
191-
m = length(list)
192-
x = Vector{N}(undef, m)
193-
y = Vector{N}(undef, m)
194-
195-
@inbounds for (i, Xi) in enumerate(list)
196-
p = element(set(Xi))
197-
x[i] = p[1]
198-
y[i] = p[2]
199-
end
200-
return x, y
140+
X = _project_reachset(R, vars)
141+
return X
201142
end
202143

203-
function _plot_reachset_list(list, N, vars, ε, Nφ)
204-
first = true
205-
x = Vector{N}()
206-
y = Vector{N}()
207-
for Ri in list
208-
Xi = _project_reachset(Ri, vars)
209-
210-
if Xi isa Intersection
211-
xcoords, ycoords = plot_recipe(Xi, ε, Nφ)
212-
213-
else
214-
Pi = isoperation(Xi) ? overapproximate(Xi, ε) : Xi
215-
vlist = convex_hull(vertices_list(Pi))
216-
m = length(vlist)
217-
if m == 0
218-
@warn "overapproximation during plotting was empty"
219-
continue
220-
end
221-
xcoords = Vector{N}(undef, m)
222-
ycoords = Vector{N}(undef, m)
223-
@inbounds for (i, v) in enumerate(vlist)
224-
xcoords[i] = v[1]
225-
ycoords[i] = v[2]
226-
end
227-
if m > 1
228-
# add first vertex to "close" the polygon
229-
push!(xcoords, xcoords[1])
230-
push!(ycoords, ycoords[1])
231-
end
232-
end
233-
isempty(xcoords) && continue
234-
235-
x_new = xcoords
236-
y_new = ycoords
237-
238-
if first
239-
first = false
240-
else
241-
push!(x, N(NaN))
242-
push!(y, N(NaN))
243-
end
244-
append!(x, x_new)
245-
append!(y, y_new)
246-
end
247-
return x, y
144+
function _plot_reachset_list(list, vars)
145+
return [_project_reachset(Ri, vars) for Ri in list]
248146
end
249147

250148
# ========================
251149
# Flowpipe plot recipes
252150
# ========================
253151

254152
@recipe function plot_list(list::Union{Flowpipe{N},AbstractVector{<:AbstractReachSet{N}}};
255-
vars=nothing,
256-
ε=N(PLOT_PRECISION),
257-
=PLOT_POLAR_DIRECTIONS) where {N}
153+
vars=nothing) where {N}
258154
_check_vars(vars)
259155

260156
label --> DEFAULT_LABEL
@@ -270,15 +166,13 @@ end
270166
_plot_singleton_list(list)
271167
else
272168
seriestype --> :shape
273-
_plot_reachset_list(list, N, vars, ε, Nφ)
169+
_plot_reachset_list(list, vars)
274170
end
275171
end
276172

277173
# composite flowpipes
278174
@recipe function plot_list(fp::Union{<:HybridFlowpipe{N},<:MixedFlowpipe{N}};
279-
vars=nothing,
280-
ε=Float64(PLOT_PRECISION),
281-
=PLOT_POLAR_DIRECTIONS) where {N}
175+
vars=nothing) where {N}
282176
_check_vars(vars)
283177

284178
label --> DEFAULT_LABEL
@@ -290,27 +184,19 @@ end
290184
seriescolor --> DEFAULT_COLOR
291185
seriestype --> :shape
292186

293-
x = Vector{N}()
294-
y = Vector{N}()
295-
187+
Xs = LazySet{N}[]
296188
for F in fp
297-
x_new, y_new = _plot_reachset_list(F, N, vars, ε, Nφ)
298-
append!(x, x_new)
299-
append!(y, y_new)
300-
push!(x, N(NaN))
301-
push!(y, N(NaN))
189+
append!(Xs, _plot_reachset_list(F, vars))
302190
end
303-
return x, y
191+
return Xs
304192
end
305193

306194
# ========================
307195
# Solution plot recipes
308196
# ========================
309197

310198
@recipe function plot_list(sol::ReachSolution{<:Flowpipe{N}};
311-
vars=nothing,
312-
ε=Float64(PLOT_PRECISION),
313-
=PLOT_POLAR_DIRECTIONS) where {N}
199+
vars=nothing) where {N}
314200
_check_vars(vars)
315201

316202
label --> DEFAULT_LABEL
@@ -327,16 +213,14 @@ end
327213
_plot_singleton_list(fp)
328214
else
329215
seriestype --> :shape
330-
_plot_reachset_list(fp, N, vars, ε, Nφ)
216+
_plot_reachset_list(fp, vars)
331217
end
332218
end
333219

334220
# compound solution flowpipes
335221
@recipe function plot_list(sol::Union{ReachSolution{<:MixedFlowpipe{N}},
336222
ReachSolution{<:HybridFlowpipe{N}}};
337-
vars=nothing,
338-
ε=Float64(PLOT_PRECISION),
339-
=PLOT_POLAR_DIRECTIONS) where {N}
223+
vars=nothing) where {N}
340224
_check_vars(vars)
341225

342226
label --> DEFAULT_LABEL
@@ -348,18 +232,12 @@ end
348232
seriescolor --> DEFAULT_COLOR
349233
seriestype --> :shape
350234

351-
x = Vector{N}()
352-
y = Vector{N}()
353-
354235
fp = flowpipe(sol)
236+
Xs = LazySet{N}[]
355237
for F in fp
356-
x_new, y_new = _plot_reachset_list(F, N, vars, ε, Nφ)
357-
append!(x, x_new)
358-
append!(y, y_new)
359-
push!(x, N(NaN))
360-
push!(y, N(NaN))
238+
append!(Xs, _plot_reachset_list(F, vars))
361239
end
362-
return x, y
240+
return Xs
363241
end
364242

365243
# TODO new plot recipe to dispatch on ShiftedFlowpipe

0 commit comments

Comments
 (0)