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

Split convert.jl into smaller files #3618

Merged
merged 1 commit into from
Sep 9, 2024
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
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
Loading