Skip to content

Commit

Permalink
Merge pull request #3103 from JuliaReach/schillic/bloating
Browse files Browse the repository at this point in the history
Revise Bloating code
  • Loading branch information
schillic authored Oct 30, 2022
2 parents b1821e3 + d92fe95 commit 9fdf5e8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 16 deletions.
6 changes: 3 additions & 3 deletions docs/src/lib/lazy_operations/Bloating.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ constraints_list(::Bloating)
center(::Bloating)
is_polyhedral(::Bloating)
```

Inherited from [`ConvexSet`](@ref):
* [`singleton_list`](@ref singleton_list(::ConvexSet))
Inherited from [`LazySet`](@ref):
* [`high`](@ref high(::LazySet))
* [`low`](@ref low(::LazySet))
47 changes: 34 additions & 13 deletions src/LazyOperations/Bloating.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,27 @@ known as *bloating*).
### Fields
- `X` -- set
- `ε` -- (positive) bloating factor
- `ε` -- (usually positive) bloating factor
- `p` -- ``p``-norm (should be ``≥ 1``; default: ``2``)
### Notes
The `Bloating` operation preserves convexity: if `X` is convex, then any
bloating of `X` is convex as well.
If `ε` is positive, then `Bloating(X, ε, p)` is equivalent to the Minkowski sum
of `X` and a ball in the `p`-norm of radius `ε` centered in the origin `O`
(i.e., `X ⊕ Ballp(p, O, ε)`).
The `Bloating` operation preserves convexity: if `X` is convex, then any
bloating of `X` is convex as well.
Some operations require, or silently assume, that `ε` is positive. Check the
documentation for further information.
"""
struct Bloating{N, S<:ConvexSet{N}} <: ConvexSet{N}
X::S
ε::N
p::N

function Bloating(X::S, ε::N, p::N=N(2)) where {N, S<:ConvexSet{N}}
function Bloating(X::S, ε::N, p::N=N(2)) where {N, S<:LazySet{N}}
@assert p >= one(N) "bloating requires a norm >= 1, but $p was given"

return new{N, S}(X, ε, p)
Expand Down Expand Up @@ -55,7 +58,12 @@ end

# helper function to compute the bloating ball
function _bloating_ball(B::Bloating{N}) where {N}
return Ballp(B.p, zeros(N, dim(B)), abs(B.ε))
return _bloating_ball(B.ε, B.p, dim(B))
end

function _bloating_ball::N, p::N, n::Int) where {N}
@assert ε >= zero(N) "cannot compute the ball for a negative bloating"
return Ballp(p, zeros(N, n), ε)
end

"""
Expand All @@ -77,7 +85,8 @@ function σ(d::AbstractVector, B::Bloating)
@assert B.ε >= 0 || B.p > 1 "the support vector for negative bloating " *
"in the 1-norm is not implemented"

return σ(d, B.X) + sign_cadlag(B.ε) * σ(d, _bloating_ball(B))
return σ(d, B.X) +
sign_cadlag(B.ε) * σ(d, _bloating_ball(abs(B.ε), B.p, dim(B)))
end

"""
Expand All @@ -97,7 +106,8 @@ The support function of the bloated set in the given direction.
function ρ(d::AbstractVector, B::Bloating)
@assert !iszero(d) "the support function in the zero direction is undefined"

return ρ(d, B.X) + sign_cadlag(B.ε) * ρ(d, _bloating_ball(B))
return ρ(d, B.X) +
sign_cadlag(B.ε) * ρ(d, _bloating_ball(abs(B.ε), B.p, dim(B)))
end

"""
Expand Down Expand Up @@ -133,6 +143,11 @@ Determine whether a bloated set is empty.
### Output
`true` iff the wrapped set is empty.
### Notes
This implementation disregards negative bloating, which could potentially turn a
non-empty set into an empty set.
"""
function isempty(B::Bloating)
return isempty(B.X)
Expand All @@ -153,7 +168,8 @@ An element in the bloated set.
### Algorithm
The implementation returns the result of `an_element` for the wrapped set.
This implementation disregards negative bloating and returns the result of
`an_element` for the wrapped set.
"""
function an_element(B::Bloating)
return an_element(B.X)
Expand All @@ -174,21 +190,21 @@ The list of constraints of the bloated set.
### Notes
The constraints list is only available for bloating in the `p`-norm for
``p = 1`` or ``p = ∞`` and if `constraints_list` is available for the unbloated
set.
The constraints list is only available for non-negative bloating in the `p`-norm
for ``p = 1`` or ``p = ∞`` and if `constraints_list` is available for the
unbloated set.
### Algorithm
We call `constraints_list` on the lazy Minkowski sum.
We call `constraints_list` on the lazy Minkowski sum with the bloating ball.
"""
function constraints_list(B::Bloating)
@assert is_polyhedral(B) "the constraints list is only available for " *
"polyhedral bloating (which requires a polyhedral base set and the " *
"1-norm or the infinity norm)"
if B.ε < 0
throw(ArgumentError("computing the constraints list of a negatively " *
"bloated set is not supported yet"))
"bloated set is not supported"))
end

return constraints_list(MinkowskiSum(B.X, _bloating_ball(B)))
Expand All @@ -206,6 +222,11 @@ Return the center of a bloated set.
### Output
The center of the wrapped set.
### Notes
This implementation disregards negative bloating, which could potentially remove
the center from the set.
"""
function center(B::Bloating)
center(B.X)
Expand Down

0 comments on commit 9fdf5e8

Please sign in to comment.