Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RIP upper_bound #779

Merged
merged 6 commits into from
Oct 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions docs/src/lib/approximations.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,3 @@ BoxDiagDirections
```

See also `overapproximate(X::LazySet, dir::AbstractDirections)::HPolytope`.

## Upper bounds

```@docs
ρ_upper_bound
```
1 change: 0 additions & 1 deletion src/Approximations/Approximations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,5 @@ include("box_approximations.jl")
include("template_directions.jl")
include("overapproximate.jl")
include("decompositions.jl")
include("upper_bounds.jl")

end # module
46 changes: 16 additions & 30 deletions src/Approximations/box_approximations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
# ===================================

"""
box_approximation(S::LazySet; upper_bound::Bool=false)::Hyperrectangle
box_approximation(S::LazySet)::Hyperrectangle

Overapproximate a convex set by a tight hyperrectangle.

### Input

- `S` -- convex set
- `upper_bound` -- (optional, default: `false`) use overapproximation in support
function computation?

### Output

Expand All @@ -24,20 +22,19 @@ of the given set in the canonical directions, and the lengths of the sides can
be recovered from the distance among support functions in the same directions.
"""
function box_approximation(S::LazySet{N};
upper_bound::Bool=false
)::Union{Hyperrectangle{N}, EmptySet{N}} where N<:Real
(c, r) = box_approximation_helper(S; upper_bound=upper_bound)
if upper_bound && r[1] < 0
(c, r) = box_approximation_helper(S)
if r[1] < 0
return EmptySet{N}()
end
return Hyperrectangle(c, r)
end

# special case: Hyperrectangle
box_approximation(S::Hyperrectangle; upper_bound::Bool=false) = S
box_approximation(S::Hyperrectangle) = S

# special case: other rectangle
box_approximation(S::AbstractHyperrectangle; upper_bound::Bool=false) =
box_approximation(S::AbstractHyperrectangle) =
Hyperrectangle(center(S), radius_hyperrectangle(S))

"""
Expand All @@ -48,7 +45,7 @@ Alias for `box_approximation`.
interval_hull = box_approximation

"""
box_approximation_symmetric(S::LazySet{N}; upper_bound::Bool=false
box_approximation_symmetric(S::LazySet{N}
)::Union{Hyperrectangle{N}, EmptySet{N}}
where {N<:Real}

Expand All @@ -57,8 +54,6 @@ Overapproximate a convex set by a tight hyperrectangle centered in the origin.
### Input

- `S` -- convex set
- `upper_bound` -- (optional, default: `false`) use overapproximation in support
function computation?

### Output

Expand All @@ -70,11 +65,10 @@ The center of the box is the origin, and the radius is obtained by computing the
maximum value of the support function evaluated at the canonical directions.
"""
function box_approximation_symmetric(S::LazySet{N};
upper_bound::Bool=false
)::Union{Hyperrectangle{N},
EmptySet{N}} where {N<:Real}
(c, r) = box_approximation_helper(S; upper_bound=upper_bound)
if upper_bound && r[1] < 0
(c, r) = box_approximation_helper(S)
if r[1] < 0
return EmptySet{N}()
end
return Hyperrectangle(zeros(N, length(c)), abs.(c) .+ r)
Expand All @@ -88,16 +82,14 @@ Alias for `box_approximation_symmetric`.
symmetric_interval_hull = box_approximation_symmetric

"""
box_approximation_helper(S::LazySet{N}; upper_bound::Bool=false
box_approximation_helper(S::LazySet{N};
) where {N<:Real}

Common code of `box_approximation` and `box_approximation_symmetric`.

### Input

- `S` -- convex set
- `upper_bound` -- (optional, default: `false`) use overapproximation in support
function computation?

### Output

Expand All @@ -115,24 +107,22 @@ The lengths of the sides can be recovered from the distance among support
functions in the same directions.
"""
@inline function box_approximation_helper(S::LazySet{N};
upper_bound::Bool=false
) where {N<:Real}
zero_N = zero(N)
one_N = one(N)
ρ_rec = upper_bound ? ρ_upper_bound : ρ
n = dim(S)
c = Vector{N}(undef, n)
r = Vector{N}(undef, n)
d = zeros(N, n)
@inbounds for i in 1:n
d[i] = one_N
htop = ρ_rec(d, S)
htop = ρ(d, S)
d[i] = -one_N
hbottom = -ρ_rec(d, S)
hbottom = -ρ(d, S)
d[i] = zero_N
c[i] = (htop + hbottom) / 2
r[i] = (htop - hbottom) / 2
if upper_bound && r[i] < 0
if r[i] < 0
# contradicting bounds => set is empty
# terminate with first radius entry being negative
r[1] = r[i]
Expand All @@ -143,16 +133,14 @@ functions in the same directions.
end

"""
ballinf_approximation(S::LazySet{N}; upper_bound::Bool=false
ballinf_approximation(S::LazySet{N};
)::BallInf{N} where {N<:Real}

Overapproximate a convex set by a tight ball in the infinity norm.

### Input

- `S` -- convex set
- `upper_bound` -- (optional, default: `false`) use overapproximation in support
function computation?

### Output

Expand All @@ -164,26 +152,24 @@ The center and radius of the box are obtained by evaluating the support function
of the given convex set along the canonical directions.
"""
function ballinf_approximation(S::LazySet{N};
upper_bound::Bool=false
)::Union{BallInf{N}, EmptySet{N}} where {N<:Real}
zero_N = zero(N)
one_N = one(N)
ρ_rec = upper_bound ? ρ_upper_bound : ρ
n = dim(S)
c = Vector{N}(undef, n)
r = zero_N
d = zeros(N, n)
@inbounds for i in 1:n
d[i] = one_N
htop = ρ_rec(d, S)
htop = ρ(d, S)
d[i] = -one_N
hbottom = -ρ_rec(d, S)
hbottom = -ρ(d, S)
d[i] = zero_N
c[i] = (htop + hbottom) / 2
rcur = (htop - hbottom) / 2
if (rcur > r)
r = rcur
elseif upper_bound && rcur < 0
elseif rcur < 0
# contradicting bounds => set is empty
return EmptySet{N}()
end
Expand Down
51 changes: 14 additions & 37 deletions src/Approximations/overapproximate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@ Otherwise the result is an ε-close approximation as a polygon.
- `S` -- convex set, assumed to be two-dimensional
- `HPolygon` -- type for dispatch
- `ε` -- (optional, default: `Inf`) error bound
- `upper_bound` -- (optional, default: `false`) currently ignored

### Output

A polygon in constraint representation.
"""
function overapproximate(S::LazySet{N},
::Type{<:HPolygon},
ε::Real=Inf;
upper_bound::Bool=false
ε::Real=Inf
)::HPolygon where {N<:Real}
@assert dim(S) == 2
if ε == Inf
Expand All @@ -59,15 +57,14 @@ function overapproximate(S::LazySet{N},
end

"""
overapproximate(S::LazySet, ε::Real; [upper_bound]::Bool=false)::HPolygon
overapproximate(S::LazySet, ε::Real)::HPolygon

Alias for `overapproximate(S, HPolygon, ε, upper_bound=upper_bound)`.
Alias for `overapproximate(S, HPolygon, ε)`.
"""
function overapproximate(S::LazySet,
ε::Real;
upper_bound::Bool=false
)::HPolygon
return overapproximate(S, HPolygon, ε; upper_bound=upper_bound)
return overapproximate(S, HPolygon, ε)
end

"""
Expand All @@ -80,18 +77,15 @@ Return an approximation of a given set as a hyperrectangle.

- `S` -- set
- `Hyperrectangle` -- type for dispatch
- `upper_bound` -- (optional, default: `false`) use overapproximation in
support function computation?

### Output

A hyperrectangle.
"""
function overapproximate(S::LazySet,
::Type{<:Hyperrectangle};
upper_bound::Bool=false
)::Union{Hyperrectangle, EmptySet}
box_approximation(S; upper_bound=upper_bound)
box_approximation(S)
end

"""
Expand All @@ -100,22 +94,19 @@ end
Alias for `overapproximate(S, Hyperrectangle)`.
"""
overapproximate(S::LazySet;
upper_bound::Bool=false
)::Union{Hyperrectangle, EmptySet} =
overapproximate(S, Hyperrectangle; upper_bound=upper_bound)
overapproximate(S, Hyperrectangle)

"""
overapproximate(S::ConvexHull{N, Zonotope{N}, Zonotope{N}},
::Type{<:Zonotope};
[upper_bound]::Bool=false)::Zonotope where {N<:Real}
::Type{<:Zonotope})::Zonotope where {N<:Real}

Overapproximate the convex hull of two zonotopes.

### Input

- `S` -- convex hull of two zonotopes of the same order
- `Zonotope` -- type for dispatch
- `upper_bound` -- (optional, default: `false`) currently ignored

### Algorithm

Expand All @@ -134,8 +125,7 @@ zonotope, which is in general expensive in high dimensions. This is further inve
in: *Zonotopes as bounding volumes, L. J. Guibas et al, Proc. of Symposium on Discrete Algorithms, pp. 803-812*.
"""
function overapproximate(S::ConvexHull{N, Zonotope{N}, Zonotope{N}},
::Type{<:Zonotope};
upper_bound::Bool=false)::Zonotope where {N<:Real}
::Type{<:Zonotope})::Zonotope where {N<:Real}
Z1, Z2 = S.X, S.Y
@assert order(Z1) == order(Z2)
center = (Z1.center+Z2.center)/2
Expand All @@ -145,8 +135,7 @@ end

"""
overapproximate(X::LazySet,
dir::AbstractDirections;
[upper_bound]::Bool=false
dir::AbstractDirections
)::HPolytope

Overapproximating a set with template directions.
Expand All @@ -155,31 +144,26 @@ Overapproximating a set with template directions.

- `X` -- set
- `dir` -- direction representation
- `upper_bound` -- (optional, default: `false`) use overapproximation in support
function computation?

### Output

A `HPolytope` overapproximating the set `X` with the directions from `dir`.
"""
function overapproximate(X::LazySet{N},
dir::AbstractDirections{N};
upper_bound::Bool=false
)::HPolytope{N} where N
ρ_rec = upper_bound ? ρ_upper_bound : ρ
halfspaces = Vector{LinearConstraint{N}}()
sizehint!(halfspaces, length(dir))
H = HPolytope(halfspaces)
for d in dir
addconstraint!(H, LinearConstraint(d, ρ_rec(d, X)))
addconstraint!(H, LinearConstraint(d, ρ(d, X)))
end
return H
end

"""
overapproximate(S::LazySet{N},
::Type{Interval};
[upper_bound]::Bool=false
::Type{Interval}
) where {N<:Real}

Return the overapproximation of a real unidimensional set with an interval.
Expand All @@ -188,15 +172,13 @@ Return the overapproximation of a real unidimensional set with an interval.

- `S` -- one-dimensional set
- `Interval` -- type for dispatch
- `upper_bound` -- (optional, default: `false`) currently ignored

### Output

An interval.
"""
function overapproximate(S::LazySet{N},
::Type{Interval};
upper_bound::Bool=false
::Type{Interval}
) where {N<:Real}
@assert dim(S) == 1
lo = σ([-one(N)], S)[1]
Expand All @@ -207,7 +189,6 @@ end
"""
overapproximate(cap::Intersection{N, <:LazySet, S},
dir::AbstractDirections{N};
[upper_bound]::Bool=false,
kwargs...
) where {N<:Real, S<:AbstractPolytope{N}}

Expand All @@ -218,8 +199,6 @@ polytope given a set of template directions.

- `cap` -- intersection of a compact set and a polytope
- `dir` -- template directions
- `upper_bound` -- (optional, default: `false`) use overapproximation in support
function computation?
- `kwargs` -- additional arguments that are passed to the support function
algorithm

Expand Down Expand Up @@ -253,7 +232,6 @@ intersection is empty.
"""
function overapproximate(cap::Intersection{N, <:LazySet, S},
dir::AbstractDirections{N};
upper_bound::Bool=false,
kwargs...
) where {N<:Real, S<:AbstractPolytope{N}}

Expand All @@ -263,12 +241,11 @@ function overapproximate(cap::Intersection{N, <:LazySet, S},
Hi = constraints_list(P)
m = length(Hi)
Q = HPolytope{N}()
ρ_rec = upper_bound ? ρ_upper_bound : ρ

for di in dir
ρ_X_Hi_min = ρ_rec(di, X ∩ Hi[1], kwargs...)
ρ_X_Hi_min = ρ(di, X ∩ Hi[1], kwargs...)
for i in 2:m
ρ_X_Hi = ρ_rec(di, X ∩ Hi[i], kwargs...)
ρ_X_Hi = ρ(di, X ∩ Hi[i], kwargs...)
if ρ_X_Hi < ρ_X_Hi_min
ρ_X_Hi_min = ρ_X_Hi
end
Expand Down
Loading