-
Notifications
You must be signed in to change notification settings - Fork 32
/
ConvexHullArray.jl
248 lines (180 loc) · 5.56 KB
/
ConvexHullArray.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
import Base.isempty
export ConvexHullArray, CHArray,
array
# ================================
# Convex hull of an array of sets
# ================================
"""
ConvexHullArray{N, S<:ConvexSet{N}} <: ConvexSet{N}
Type that represents the symbolic convex hull of a finite number of sets.
### Fields
- `array` -- array of sets
### Notes
The `EmptySet` is the neutral element for `ConvexHullArray`.
Constructors:
- `ConvexHullArray(array::Vector{<:ConvexSet})` -- default constructor
- `ConvexHullArray([n]::Int=0, [N]::Type=Float64)`
-- constructor for an empty hull with optional size hint and numeric type
### Examples
Convex hull of 100 two-dimensional balls whose centers follow a sinusoidal:
```jldoctest
julia> b = [Ball2([2*pi*i/100, sin(2*pi*i/100)], 0.05) for i in 1:100];
julia> c = ConvexHullArray(b);
```
"""
struct ConvexHullArray{N, S<:ConvexSet{N}} <: ConvexSet{N}
array::Vector{S}
end
isoperationtype(::Type{<:ConvexHullArray}) = true
isconvextype(::Type{<:ConvexHullArray}) = true
# constructor for an empty hull with optional size hint and numeric type
function ConvexHullArray(n::Int=0, N::Type=Float64)
a = Vector{ConvexSet{N}}()
sizehint!(a, n)
return ConvexHullArray(a)
end
# EmptySet is the neutral element for ConvexHullArray
@neutral(ConvexHullArray, EmptySet)
# Universe is the absorbing element for ConvexHullArray
@absorbing(ConvexHullArray, Universe)
# add functions connecting ConvexHull and ConvexHullArray
@declare_array_version(ConvexHull, ConvexHullArray)
"""
CHArray
Alias for `ConvexHullArray`.
"""
const CHArray = ConvexHullArray
"""
array(cha::ConvexHullArray)
Return the array of a convex hull of a finite number of sets.
### Input
- `cha` -- convex hull array
### Output
The array of a convex hull of a finite number of sets.
"""
function array(cha::ConvexHullArray)
return cha.array
end
"""
dim(cha::ConvexHullArray)
Return the dimension of the convex hull of a finite number of sets.
### Input
- `cha` -- convex hull array
### Output
The ambient dimension of the convex hull of a finite number of sets.
"""
function dim(cha::ConvexHullArray)
@assert !isempty(cha.array) "an empty convex hull is not allowed"
return dim(cha.array[1])
end
"""
σ(d::AbstractVector, cha::ConvexHullArray)
Return the support vector of a convex hull array in a given direction.
### Input
- `d` -- direction
- `cha` -- convex hull array
"""
function σ(d::AbstractVector, cha::ConvexHullArray)
@assert !isempty(cha.array) "an empty convex hull is not allowed"
svec = d
N = eltype(d)
rmax = N(-Inf)
for chi in cha.array
si = σ(d, chi)
ri = dot(d, si)
if ri > rmax
rmax = ri
svec = si
end
end
return svec
end
"""
ρ(d::AbstractVector, cha::ConvexHullArray)
Return the support function of a convex hull array in a given direction.
### Input
- `d` -- direction
- `cha` -- convex hull array
### Output
The support function of the convex hull array in the given direction.
### Algorithm
This algorihm calculates the maximum over all ``ρ(d, X_i)`` where the
``X_1, …, X_k`` are the sets in the array `cha`.
"""
function ρ(d::AbstractVector, cha::ConvexHullArray)
return maximum(ρ(d, Xi) for Xi in array(cha))
end
"""
isbounded(cha::ConvexHullArray)
Determine whether a convex hull of a finite number of sets is bounded.
### Input
- `cha` -- convex hull of a finite number of sets
### Output
`true` iff all wrapped sets are bounded.
"""
function isbounded(cha::ConvexHullArray)
return all(isbounded, cha.array)
end
function isboundedtype(::Type{<:ConvexHullArray{N, S}}) where {N, S}
return isboundedtype(S)
end
"""
isempty(cha::ConvexHullArray)
Return if a convex hull array is empty or not.
### Input
- `cha` -- convex hull array
### Output
`true` iff all wrapped sets are empty.
"""
function isempty(cha::ConvexHullArray)
return all(isempty, array(cha))
end
"""
vertices_list(cha::ConvexHullArray; apply_convex_hull::Bool=true,
backend=nothing)
Return the list of vertices of the convex hull of a finite number of sets.
### Input
- `cha` -- convex hull of a finite number of sets
- `apply_convex_hull` -- (optional, default: `true`) if `true`, post-process the
vertices using a convex-hull algorithm
- `backend` -- (optional, default: `nothing`) backend for computing
the convex hull (see argument `apply_convex_hull`)
### Output
The list of vertices.
"""
function vertices_list(cha::ConvexHullArray;
apply_convex_hull::Bool=true,
backend=nothing)
vlist = vcat([vertices_list(Xi) for Xi in array(cha)]...)
if apply_convex_hull
convex_hull!(vlist, backend=backend)
end
return vlist
end
# list of constraints of the convex hull array of singletons
function constraints_list(X::ConvexHullArray{N, Singleton{N, VT}}) where {N, VT}
n = dim(X)
ST = n == 2 ? VPolygon : VPolytope
V = convert(ST, X)
return constraints_list(V)
end
# membership in convex hull array of singletons
function ∈(x::AbstractVector, X::ConvexHullArray)
n = length(x)
ST = n == 2 ? VPolygon : VPolytope
V = convert(ST, X)
return x ∈ V
end
function concretize(cha::ConvexHullArray)
a = array(cha)
@assert !isempty(a) "an empty convex hull is not allowed"
X = cha
@inbounds for (i, Y) in enumerate(a)
if i == 1
X = concretize(Y)
else
X = convex_hull(X, concretize(Y))
end
end
return X
end