Skip to content

Commit

Permalink
Merge pull request #3618 from JuliaReach/schillic/convert
Browse files Browse the repository at this point in the history
Split `convert.jl` into smaller files
  • Loading branch information
schillic authored Sep 9, 2024
2 parents 1ddf897 + 783d9ad commit 24e8b1b
Show file tree
Hide file tree
Showing 20 changed files with 967 additions and 948 deletions.
38 changes: 38 additions & 0 deletions src/Convert/AffineMap.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
convert(::Type{STAR}, P::AbstractPolyhedron{N}) where {N}
Convert a polyhedral set to a star set represented as a lazy affine map.
### Input
- `STAR` -- target type
- `P` -- polyhedral set
### Output
A star set.
"""
function convert(::Type{STAR}, P::AbstractPolyhedron{N}) where {N}
n = dim(P)
c = zeros(N, n)
V = Matrix(one(N) * I, n, n)
return AffineMap(V, P, c)
end

"""
convert(::Type{STAR}, X::Star)
Convert a star set to its equivalent representation as a lazy affine map.
### Input
- `STAR` -- target type
- `X` -- star set
### Output
A star set.
"""
function Base.convert(::Type{STAR}, X::Star)
return AffineMap(X.V, X.P, X.c)
end
26 changes: 26 additions & 0 deletions src/Convert/CartesianProduct.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
convert(::Type{CartesianProduct{N, Interval{N}, Interval{N}}},
H::AbstractHyperrectangle{N}) where {N}
Convert a two-dimensional hyperrectangle to the Cartesian product of two
intervals.
### Input
- `CartesianProduct` -- target type
- `H` -- hyperrectangle
### Output
The Cartesian product of two intervals.
"""
function convert(::Type{CartesianProduct{N,Interval{N},Interval{N}}},
H::AbstractHyperrectangle{N}) where {N}
@assert dim(H) == 2 "the hyperrectangle must be two-dimensional to " *
"convert it to the Cartesian product of two intervals, but it is " *
"$(dim(H))-dimensional; consider converting it to a " *
"`CartesianProductArray{$N, Interval{$N}}` instead"
I1 = Interval(low(H, 1), high(H, 1))
I2 = Interval(low(H, 2), high(H, 2))
return CartesianProduct(I1, I2)
end
20 changes: 20 additions & 0 deletions src/Convert/CartesianProductArray.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
convert(::Type{CartesianProductArray{N, Interval{N}}},
H::AbstractHyperrectangle{N}) where {N}
Convert a hyperrectangle to the Cartesian product array of intervals.
### Input
- `CartesianProductArray` -- target type
- `H` -- hyperrectangle
### Output
The Cartesian product of a finite number of intervals.
"""
function convert(::Type{CartesianProductArray{N,Interval{N}}},
H::AbstractHyperrectangle{N}) where {N}
Iarray = [Interval(low(H, i), high(H, i)) for i in 1:dim(H)]
return CartesianProductArray(Iarray)
end
2 changes: 2 additions & 0 deletions src/Convert/HPolyhedron.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# make a copy of the constraints
Base.convert(::Type{HPolyhedron}, P::HPolytope) = HPolyhedron(copy(constraints_list(P)))
2 changes: 2 additions & 0 deletions src/Convert/HPolytope.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# make a copy of the constraints
Base.convert(::Type{HPolytope}, P::HPolyhedron) = HPolytope(copy(constraints_list(P)))
10 changes: 10 additions & 0 deletions src/Convert/Hyperplane.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function Base.convert(::Type{Hyperplane}, P::HPolyhedron; skip_check::Bool=false)
# check that the number of constraints is fine
if !skip_check && !ishyperplanar(P)
throw(ArgumentError("the polyhedron is not hyperplanar: $P"))
end

# construct hyperplane from first constraint
c1 = @inbounds first(constraints_list(P))
return Hyperplane(c1.a, c1.b)
end
136 changes: 136 additions & 0 deletions src/Convert/Hyperrectangle.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
"""
convert(::Type{Hyperrectangle}, cpa::CartesianProductArray{N, HN})
where {N, HN<:AbstractHyperrectangle}
Convert the Cartesian product of a finite number of hyperrectangular sets to
a single hyperrectangle.
### Input
- `Hyperrectangle` -- target type
- `S` -- Cartesian product array of hyperrectangular set
### Output
A hyperrectangle.
### Algorithm
This implementation uses the `center` and `radius_hyperrectangle` methods of
`AbstractHyperrectangle`.
"""
function convert(::Type{Hyperrectangle},
cpa::CartesianProductArray{N,HN}) where {N,HN<:AbstractHyperrectangle}
n = dim(cpa)
c = Vector{N}(undef, n)
r = Vector{N}(undef, n)
i = 1
@inbounds for block_set in cpa
j = i + dim(block_set) - 1
c[i:j] = center(block_set)
r[i:j] = radius_hyperrectangle(block_set)
i = j + 1
end
return Hyperrectangle(c, r)
end

"""
convert(::Type{Hyperrectangle}, cp::CartesianProduct{N, HN1, HN2})
where {N, HN1<:AbstractHyperrectangle, HN2<:AbstractHyperrectangle}
Convert the Cartesian product of two hyperrectangular sets to a single
hyperrectangle.
### Input
- `Hyperrectangle` -- target type
- `S` -- Cartesian product of two hyperrectangular sets
### Output
A hyperrectangle.
### Algorithm
The result is obtained by concatenating the center and radius of each
hyperrectangle. This implementation uses the `center` and
`radius_hyperrectangle` methods.
"""
function convert(::Type{Hyperrectangle},
cp::CartesianProduct{N,HN1,HN2}) where {N,HN1<:AbstractHyperrectangle,
HN2<:AbstractHyperrectangle}
X, Y = first(cp), second(cp)
c = vcat(center(X), center(Y))
r = vcat(radius_hyperrectangle(X), radius_hyperrectangle(Y))
return Hyperrectangle(c, r)
end

"""
convert(::Type{Hyperrectangle},
cpa::CartesianProductArray{N, IN}) where {N, IN<:Interval}
Convert the Cartesian product of a finite number of intervals to a single
hyperrectangle.
### Input
- `Hyperrectangle` -- target type
- `S` -- Cartesian product array of intervals
### Output
A hyperrectangle.
### Algorithm
This implementation uses the `min` and `max` methods of `Interval` to reduce
the allocations and improve performance (see LazySets#1143).
"""
function convert(::Type{Hyperrectangle},
cpa::CartesianProductArray{N,IN}) where {N,IN<:Interval}
# since the sets are intervals, the dimension of cpa is its length
n = length(array(cpa))
l = Vector{N}(undef, n)
h = Vector{N}(undef, n)
@inbounds for (i, Ii) in enumerate(array(cpa))
l[i] = min(Ii)
h[i] = max(Ii)
end
return Hyperrectangle(; low=l, high=h)
end

"""
convert(::Type{Hyperrectangle}, r::Rectification{N, AH})
where {N, AH<:AbstractHyperrectangle}
Convert a rectification of a hyperrectangle to a hyperrectangle.
### Input
- `Hyperrectangle` -- target type
- `r` -- rectification of a hyperrectangle
### Output
A `Hyperrectangle`.
"""
function convert(::Type{Hyperrectangle},
r::Rectification{N,AH}) where {N,AH<:AbstractHyperrectangle}
return rectify(r.X)
end

function convert(::Type{Hyperrectangle}, Z::AbstractZonotope{N}) where {N}
c = center(Z)
n = length(c)
r = zeros(N, n)
@inbounds for cj in generators(Z)
i = findfirst(!=(zero(N)), cj)
if isnothing(i)
continue
end
@assert isnothing(findfirst(!=(zero(N)), @view cj[(i + 1):end])) "the zonotope " *
"is not hyperrectangular"
r[i] += cj[i] # `+` because to allow for multiple generators in dimension i
end
return Hyperrectangle(c, r)
end
36 changes: 36 additions & 0 deletions src/Convert/Interval.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""
convert(::Type{Interval}, r::Rectification{N, IN}) where {N, IN<:Interval}
Convert a rectification of an interval to an interval.
### Input
- `Interval` -- target type
- `r` -- rectification of an interval
### Output
An `Interval`.
"""
function convert(::Type{Interval},
r::Rectification{N,IN}) where {N,IN<:Interval}
return Interval(rectify([min(r.X), max(r.X)]))
end

"""
convert(::Type{Interval}, ms::MinkowskiSum{N, IT, IT}) where {N, IT<:Interval}
Convert the Minkowski sum of two intervals to an interval.
### Input
- `Interval` -- target type
- `ms` -- Minkowski sum of two intervals
### Output
An interval.
"""
function convert(::Type{Interval}, ms::MinkowskiSum{N,IT,IT}) where {N,IT<:Interval}
return concretize(ms)
end
19 changes: 19 additions & 0 deletions src/Convert/MinkowskiSumArray.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
convert(::Type{MinkowskiSumArray},
X::MinkowskiSum{N, ST, MinkowskiSumArray{N, ST}}) where {N, ST}
Convert the Minkowski sum of a Minkowski sum array to a Minkowski sum array.
### Input
- `MinkowskiSumArray` -- target type
- `X` -- Minkowski sum of a Minkowski sum array
### Output
A Minkowski sum array.
"""
function convert(::Type{MinkowskiSumArray},
X::MinkowskiSum{N,ST,MinkowskiSumArray{N,ST}}) where {N,ST}
return MinkowskiSumArray(vcat(first(X), array(second(X))))
end
57 changes: 57 additions & 0 deletions src/Convert/SimpleSparsePolynomialZonotope.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
convert(::Type{SimpleSparsePolynomialZonotope}, Z::AbstractZonotope)
Convert a zonotope to a simple sparse polynomial zonotope.
### Input
- `SimpleSparsePolynomialZonotope` -- target type
- `Z` -- zonotopic set
### Output
A simple sparse polynomial zonotope.
### Algorithm
This method implements Proposition 3 in [1].
[1] Kochdumper, Althoff. *Sparse polynomial zonotopes - a novel set
representation for reachability analysis*. 2021
"""
function Base.convert(::Type{SimpleSparsePolynomialZonotope}, Z::AbstractZonotope)
c = center(Z)
G = genmat(Z)
n = ngens(Z)
E = Matrix(1 * I, n, n)
return SimpleSparsePolynomialZonotope(c, G, E)
end

"""
convert(::Type{SimpleSparsePolynomialZonotope}, SPZ::SparsePolynomialZonotope)
Convert a sparse polynomial zonotope to simple sparse polynomial zonotope.
### Input
- `SimpleSparsePolynomialZonotope` -- target type
- `SPZ` -- sparse polynomial zonotope
### Output
A simple sparse polynomial zonotope.
### Algorithm
The method implements Proposition 3.1.4 from [1].
[1] Kochdumper, Niklas. *Extensions of polynomial zonotopes and their application to
verification of cyber-physical systems.* PhD diss., Technische Universität München, 2022.
"""
function Base.convert(::Type{SimpleSparsePolynomialZonotope}, SPZ::SparsePolynomialZonotope)
c = center(SPZ)
G = hcat(genmat_dep(SPZ), genmat_indep(SPZ))
n = ngens_indep(SPZ)
E = cat(expmat(SPZ), Matrix(1 * I, n, n); dims=(1, 2))
return SimpleSparsePolynomialZonotope(c, G, E)
end
5 changes: 5 additions & 0 deletions src/Convert/Singleton.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function convert(::Type{Singleton},
cp::CartesianProduct{N,S1,S2}) where {N,S1<:AbstractSingleton,
S2<:AbstractSingleton}
return Singleton(vcat(element(first(cp)), element(second(cp))))
end
Loading

0 comments on commit 24e8b1b

Please sign in to comment.