Skip to content

Commit

Permalink
Merge pull request #3533 from JuliaReach/schillic/interval_more
Browse files Browse the repository at this point in the history
Add more and better operations for `Interval`
  • Loading branch information
schillic authored Jul 2, 2024
2 parents 625eb2d + 36c3dba commit 30950f3
Show file tree
Hide file tree
Showing 21 changed files with 234 additions and 42 deletions.
57 changes: 49 additions & 8 deletions docs/src/lib/sets/Interval.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,9 @@ chebyshev_center_radius(::Interval)
constraints_list(::Interval)
diameter(::Interval, ::Real=Inf)
dim(::Interval)
high(::Interval)
∈(::AbstractVector, ::Interval)
isflat(::Interval)
linear_map(::AbstractMatrix, ::Interval)
low(::Interval)
min(::Interval)
max(::Interval)
ngens(::Interval)
radius_hyperrectangle(::Interval)
radius_hyperrectangle(::Interval{N}, ::Int) where {N}
Expand All @@ -52,6 +48,8 @@ isdisjoint(::Interval, ::Interval, ::Bool=false)
minkowski_difference(::Interval, ::Interval)
minkowski_sum(::Interval, ::Interval)
plot_recipe(::Interval{N}, ::Any=zero(N)) where {N}
min(::Interval)
max(::Interval)
-(::Interval, ::Interval)
*(::Interval, ::Interval)
```
Expand All @@ -61,21 +59,65 @@ CurrentModule = LazySets.API
```

Undocumented implementations:
* [`affine_map`](@ref affine_map(::AbstractMatrix, ::LazySet, ::AbstractVector))
* [`complement`](@ref complement(::LazySet))
* [`exponential_map`](@ref exponential_map(::AbstractMatrix, ::LazySet))
* [`extrema`](@ref extrema(::LazySet))
* [`extrema`](@ref extrema(::LazySet, ::Int))
* [`high`](@ref high(::LazySet, ::Int))
* [`high`](@ref high(::LazySet))
* [`isoperationtype`](@ref isoperationtype(::Type{<:LazySet}))
* [`low`](@ref low(::LazySet, ::Int))
* [`low`](@ref low(::LazySet))
* [`norm`](@ref norm(::LazySet, ::Real))
* [`permute`](@ref permute(::LazySet, ::AbstractVector{Int}))
* [`project`](@ref project(::LazySet, ::AbstractVector{Int}))
* [`radius`](@ref radius(::LazySet, ::Real))
* [`volume`](@ref volume(::LazySet))
* [`convex_hull`](@ref convex_hull(::LazySet, ::LazySet))
* [`distance`](@ref distance(::LazySet, ::LazySet))
* [``](@ref ≈(::LazySet, ::LazySet))
* [`isequivalent`](@ref isequivalent(::LazySet, ::LazySet))
* [``](@ref ⊂(::LazySet, ::LazySet))

```@meta
CurrentModule = LazySets
```

Inherited from [`LazySet`](@ref):
* [`concretize`](@ref concretize(::LazySet))
* [`constraints`](@ref constraints(::LazySet))
* [`eltype`](@ref eltype(::Type{<:LazySet}))
* [`eltype`](@ref eltype(::LazySet))
* [`isoperation`](@ref isoperation(::LazySet))
* [`singleton_list`](@ref singleton_list(::LazySet))
* [`vertices`](@ref vertices(::LazySet))
* [`is_interior_point`](@ref is_interior_point(::AbstractVector, ::LazySet))
* [`sample`](@ref sample(::LazySet, ::Int))
* [`==`](@ref ==(::LazySet, ::LazySet))

Inherited from [`AbstractPolyhedron`](@ref):
* [`is_polyhedral`](@ref is_polyhedral(::AbstractPolyhedron))

Inherited from [`ConvexSet`](@ref):

```@meta
CurrentModule = LazySets.API
```

* [`linear_combination`](@ref linear_combination(::LazySet, ::LazySet))

```@meta
CurrentModule = LazySets
```

Inherited from [`AbstractPolytope`](@ref):
* [`isbounded`](@ref isbounded(::AbstractPolytope))
* [`isuniversal`](@ref isuniversal(::AbstractPolytope{N}, ::Bool=false) where {N})
* [`isboundedtype`](@ref isboundedtype(::Type{<:AbstractPolytope}))

Inherited from [`AbstractCentrallySymmetricPolytope`](@ref):
* [`isempty`](@ref isempty(::AbstractCentrallySymmetricPolytope))
* [`isuniversal`](@ref isuniversal(::AbstractCentrallySymmetricPolytope{N}, ::Bool=false) where {N})

Inherited from [`AbstractZonotope`](@ref):
* [`order`](@ref order(::AbstractZonotope))
Expand All @@ -84,9 +126,8 @@ Inherited from [`AbstractZonotope`](@ref):
Inherited from [`AbstractHyperrectangle`](@ref):
* [`generators`](@ref generators(::AbstractHyperrectangle))
* [`genmat`](@ref genmat(::AbstractHyperrectangle))
* [`high`](@ref high(::AbstractHyperrectangle, ::Int))
* [`low`](@ref low(::AbstractHyperrectangle, ::Int))
* [`norm`](@ref norm(::AbstractHyperrectangle, ::Real))
* [`isconvextype`](@ref isconvextype(::Type{<:AbstractHyperrectangle}))
* [`cartesian_product`](@ref cartesian_product(::AbstractHyperrectangle, ::AbstractHyperrectangle))

Some additional functionality is available for `IntervalArithmetic.Interval`s:

Expand Down
2 changes: 2 additions & 0 deletions src/API/Binary/linear_combination.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ The linear combination of two sets ``X`` and ``Y`` is defined as
```math
\\left\\{\\frac{1}{2}(1+λ)x + \\frac{1}{2}(1-λ)y \\mid x ∈ X, y ∈ Y, λ ∈ [-1, 1]\\right\\}.
```
If ``X`` and ``Y`` are convex, their linear combination is identical with their convex hull.
"""
function linear_combination(::LazySet, ::LazySet) end
4 changes: 4 additions & 0 deletions src/ConcreteOperations/linear_combination.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ function linear_combination(P1::SimpleSparsePolynomialZonotope,

return SimpleSparsePolynomialZonotope(c, G, E)
end

function linear_combination(X::ConvexSet, Y::ConvexSet)
return convex_hull(X, Y)
end
3 changes: 3 additions & 0 deletions src/Interfaces/LazySet.jl
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,9 @@ end
The default implementation applies the functions `exp` and `linear_map`.
"""
function exponential_map(M::AbstractMatrix, X::LazySet)
n = dim(X)
@assert size(M) == (n, n) "cannot apply an exponential map of dimension " *
"$(size(M)) to an $n-dimensional set"
return linear_map(exp(M), X)
end

Expand Down
26 changes: 20 additions & 6 deletions src/Sets/Interval/IntervalModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ using ReachabilityBase.Comparison
using ReachabilityBase.Distribution: reseed!
import IntervalArithmetic as IA

@reexport import ..API: an_element, center, constraints_list, diameter, dim, high, ,
isoperationtype, linear_map, low, rand, rectify, reflect, scale, ρ, σ,
translate, vertices_list,
difference, intersection, isdisjoint, , minkowski_difference,
minkowski_sum
@reexport import ..API: affine_map, an_element, center, complement, constraints_list,
convex_hull, diameter, dim, exponential_map, extrema, high, ,
isoperationtype, linear_map, low, norm, permute, project, rand,
rectify, reflect, scale, ρ, σ, translate, vertices_list, volume,
difference, distance, intersection, , isdisjoint, isequivalent,
, , minkowski_difference, minkowski_sum
@reexport import ..LazySets: chebyshev_center_radius, isflat, ngens, plot_recipe,
radius_hyperrectangle, split
import Base: convert, -, *, min, max
Expand All @@ -25,20 +26,28 @@ export Interval

include("Interval.jl")

include("affine_map.jl")
include("an_element.jl")
include("center.jl")
include("chebyshev_center_radius.jl")
include("complement.jl")
include("constraints_list.jl")
include("convert.jl")
include("convex_hull.jl")
include("diameter.jl")
include("dim.jl")
include("exponential_map.jl")
include("extrema.jl")
include("high.jl")
include("in.jl")
include("isflat.jl")
include("isoperationtype.jl")
include("linear_map.jl")
include("low.jl")
include("isoperationtype.jl")
include("ngens.jl")
include("norm.jl")
include("permute.jl")
include("project.jl")
include("radius.jl")
include("radius_hyperrectangle.jl")
include("rand.jl")
Expand All @@ -50,10 +59,15 @@ include("support_vector.jl")
include("support_function.jl")
include("translate.jl")
include("vertices_list.jl")
include("volume.jl")

include("difference.jl")
include("distance.jl")
include("intersection.jl")
include("isapprox.jl")
include("isdisjoint.jl")
include("isequivalent.jl")
include("isstrictsubset.jl")
include("issubset.jl")
include("minkowski_difference.jl")
include("minkowski_sum.jl")
Expand Down
10 changes: 10 additions & 0 deletions src/Sets/Interval/affine_map.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function affine_map(M, X::Interval, v::AbstractVector; kwargs...)
@assert size(M, 2) == 1 "cannot apply an affine map of dimension $(size(M, 2)) " *
"to an interval"
@assert size(M, 1) == length(v) "cannot apply an affine map of matrix dimension " *
"$(size(M, 1)) and translation dimension $(length(v))"
@inbounds if length(v) == 1
return Interval(M[1, 1] * X.dat + v[1])
end
return translate(linear_map(M, X; kwargs...), v)
end
6 changes: 6 additions & 0 deletions src/Sets/Interval/complement.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function complement(X::Interval)
N = eltype(X)
L = HalfSpace(SingleEntryVector(1, 1, one(N)), min(X))
H = HalfSpace(SingleEntryVector(1, 1, -one(N)), -max(X))
return UnionSet(L, H)
end
3 changes: 3 additions & 0 deletions src/Sets/Interval/convex_hull.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function convex_hull(I1::Interval, I2::Interval)
return Interval(min(min(I1), min(I2)), max(max(I1), max(I2)))
end
7 changes: 7 additions & 0 deletions src/Sets/Interval/distance.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function distance(X::Interval, Y::Interval; p::Real=2)
d = max(min(X) - max(Y), min(Y) - max(X))
if d < 0
return zero(d)
end
return d
end
6 changes: 6 additions & 0 deletions src/Sets/Interval/exponential_map.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function exponential_map(M::AbstractMatrix, X::Interval)
@assert size(M) == (1, 1) "cannot apply an exponential map of dimension " *
"$(size(M)) to an interval"
@inbounds e = exp(M[1, 1])
return Interval(e * X.dat)
end
12 changes: 12 additions & 0 deletions src/Sets/Interval/extrema.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# the implementations here are equivalent to the default implementation for
# `LazySet`, but more efficient than the more specific implementations for
# subtypes

function extrema(X::Interval, i::Int)
@assert i == 1 "an interval has dimension 1, but the index is $i"
return (min(X), max(X))
end

function extrema(X::Interval)
return ([min(X)], [max(X)])
end
20 changes: 6 additions & 14 deletions src/Sets/Interval/high.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
"""
high(x::Interval)
Return the higher coordinate of an interval set.
### Input
- `x` -- interval
### Output
function high(X::Interval, i::Int)
@assert i == 1 "an interval has dimension 1, but the index is $i"
return max(X)
end

A vector with the higher coordinate of the interval.
"""
function high(x::Interval)
return [x.dat.hi]
function high(X::Interval)
return [max(X)]
end
3 changes: 3 additions & 0 deletions src/Sets/Interval/isapprox.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function (I1::Interval, I2::Interval)
return _isapprox(min(I1), min(I2)) && _isapprox(max(I1), max(I2))
end
3 changes: 3 additions & 0 deletions src/Sets/Interval/isequivalent.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function isequivalent(I1::Interval, I2::Interval)
return I1 I2
end
11 changes: 11 additions & 0 deletions src/Sets/Interval/isstrictsubset.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function (X::Interval, Y::Interval, witness::Bool=false)
if min(X) < min(Y) || max(X) > max(Y)
return _witness_result_empty(witness, false, X, Y)
end
if min(X) > min(Y)
return witness ? (true, low(Y)) : true
elseif max(Y) > max(X)
return witness ? (true, high(Y)) : true
end
return _witness_result_empty(witness, false, X, Y)
end
20 changes: 6 additions & 14 deletions src/Sets/Interval/low.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
"""
low(x::Interval)
Return the lower coordinate of an interval set.
### Input
- `x` -- interval
### Output
function low(X::Interval, i::Int)
@assert i == 1 "an interval has dimension 1, but the index is $i"
return min(X)
end

A vector with the lower coordinate of the interval.
"""
function low(x::Interval)
return [x.dat.lo]
function low(X::Interval)
return [min(X)]
end
3 changes: 3 additions & 0 deletions src/Sets/Interval/norm.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function norm(X::Interval, p::Real=Inf)
return max(abs(min(X)), abs(max(X)))
end
4 changes: 4 additions & 0 deletions src/Sets/Interval/permute.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function permute(X::Interval, p::AbstractVector{Int})
@assert length(p) == 1 && p[1] == 1 "invalid permutation vector $p"
return X
end
4 changes: 4 additions & 0 deletions src/Sets/Interval/project.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
function project(X::Interval, block::AbstractVector{Int}; kwargs...)
@assert length(block) == 1 && block[1] == 1 "invalid permutation vector $block"
return X
end
3 changes: 3 additions & 0 deletions src/Sets/Interval/volume.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function volume(X::Interval)
return max(X) - min(X)
end
Loading

0 comments on commit 30950f3

Please sign in to comment.