-
Notifications
You must be signed in to change notification settings - Fork 32
/
MinkowskiSum.jl
303 lines (206 loc) · 6.46 KB
/
MinkowskiSum.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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
import Base: +, getindex
export MinkowskiSum, ⊕,
MinkowskiSum!,
swap
"""
MinkowskiSum{N, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N}
Type that represents the Minkowski sum of two sets, i.e., the set
```math
X ⊕ Y = \\{x + y : x ∈ X, y ∈ Y\\}.
```
### Fields
- `X` -- set
- `Y` -- set
### Notes
The `ZeroSet` is the neutral element and the `EmptySet` is the absorbing element
for `MinkowskiSum`.
The Minkowski sum preserves convexity: if the set arguments are convex, then
their Minkowski sum is convex as well.
"""
struct MinkowskiSum{N,S1<:LazySet{N},S2<:LazySet{N}} <: LazySet{N}
X::S1
Y::S2
# default constructor with dimension check
function MinkowskiSum(X::LazySet{N}, Y::LazySet{N}) where {N}
@assert dim(X) == dim(Y) "sets in a Minkowski sum must have the same dimension"
return new{N,typeof(X),typeof(Y)}(X, Y)
end
end
"""
+(X::LazySet, Y::LazySet)
Alias for the Minkowski sum.
"""
+(X::LazySet, Y::LazySet) = MinkowskiSum(X, Y)
"""
⊕(X::LazySet, Y::LazySet)
Alias for the Minkowski sum.
### Notes
The function symbol can be typed via `\\oplus<tab>`.
"""
⊕(X::LazySet, Y::LazySet) = MinkowskiSum(X, Y)
isoperationtype(::Type{<:MinkowskiSum}) = true
concrete_function(::Type{<:MinkowskiSum}) = minkowski_sum
isconvextype(::Type{MinkowskiSum{N,S1,S2}}) where {N,S1,S2} = isconvextype(S1) && isconvextype(S2)
is_polyhedral(ms::MinkowskiSum) = is_polyhedral(ms.X) && is_polyhedral(ms.Y)
# ZeroSet is the neutral element for MinkowskiSum
@neutral(MinkowskiSum, ZeroSet)
# EmptySet and Universe are the absorbing elements for MinkowskiSum
@absorbing(MinkowskiSum, EmptySet)
# @absorbing(MinkowskiSum, Universe) # TODO problematic
# interface for binary set operations
Base.first(ms::MinkowskiSum) = ms.X
second(ms::MinkowskiSum) = ms.Y
@declare_binary_operation(MinkowskiSum)
"""
swap(ms::MinkowskiSum)
Return a new `MinkowskiSum` object with the arguments swapped.
### Input
- `ms` -- Minkowski sum of two sets
### Output
A new `MinkowskiSum` object with the arguments swapped.
"""
function swap(ms::MinkowskiSum)
return MinkowskiSum(ms.Y, ms.X)
end
"""
dim(ms::MinkowskiSum)
Return the dimension of a Minkowski sum of two sets.
### Input
- `ms` -- Minkowski sum of two sets
### Output
The ambient dimension of the Minkowski sum of two sets.
"""
function dim(ms::MinkowskiSum)
return dim(ms.X)
end
"""
σ(d::AbstractVector, ms::MinkowskiSum)
Return a support vector of a Minkowski sum of two sets.
### Input
- `d` -- direction
- `ms` -- Minkowski sum of two sets
### Output
A support vector in the given direction.
If the direction has norm zero, the result depends on the summand sets.
### Algorithm
A valid support vector in direction ``d`` of the Minkowski sum of two sets ``X``
and ``Y`` is the sum of the support vectors of ``X`` and ``Y`` in direction
``d``.
"""
function σ(d::AbstractVector, ms::MinkowskiSum)
return σ(d, ms.X) + σ(d, ms.Y)
end
"""
ρ(d::AbstractVector, ms::MinkowskiSum)
Evaluate the support function of a Minkowski sum of two sets.
### Input
- `d` -- direction
- `ms` -- Minkowski sum of two sets
### Output
The evaluation of the support function in the given direction.
### Algorithm
The support function in direction ``d`` of the Minkowski sum of two sets ``X``
and ``Y`` is the sum of the support functions of ``X`` and ``Y`` in direction
``d``.
"""
function ρ(d::AbstractVector, ms::MinkowskiSum)
return ρ(d, ms.X) + ρ(d, ms.Y)
end
"""
isbounded(ms::MinkowskiSum)
Check whether a Minkowski sum of two sets is bounded.
### Input
- `ms` -- Minkowski sum of two sets
### Output
`true` iff both wrapped sets are bounded.
"""
function isbounded(ms::MinkowskiSum)
return isbounded(ms.X) && isbounded(ms.Y)
end
function isboundedtype(::Type{MinkowskiSum{N,S1,S2}}) where {N,S1,S2}
return isboundedtype(S1) && isboundedtype(S2)
end
"""
isempty(ms::MinkowskiSum)
Check whether a Minkowski sum of two sets is empty.
### Input
- `ms` -- Minkowski sum of two sets
### Output
`true` iff any of the wrapped sets are empty.
"""
function isempty(ms::MinkowskiSum)
return isempty(ms.X) || isempty(ms.Y)
end
"""
center(ms::MinkowskiSum)
Return the center of a Minkowski sum of two centrally-symmetric sets.
### Input
- `ms` -- Minkowski sum of two centrally-symmetric sets
### Output
The center of the Minkowski sum.
"""
function center(ms::MinkowskiSum)
return center(ms.X) + center(ms.Y)
end
"""
constraints_list(ms::MinkowskiSum)
Return a list of constraints of the Minkowski sum of two polyhedral sets.
### Input
- `ms` -- Minkowski sum of two polyhedral sets
### Output
The list of constraints of the Minkowski sum.
### Algorithm
We compute a concrete set representation via `minkowski_sum` and call
`constraints_list` on the result.
"""
function constraints_list(ms::MinkowskiSum)
return constraints_list(minkowski_sum(ms.X, ms.Y))
end
"""
∈(x::AbstractVector, ms::MinkowskiSum{N, S1, S2})
where {N, S1<:AbstractSingleton}
Check whether a given point is contained in the Minkowski sum of a singleton
and another set.
### Input
- `x` -- point/vector
- `ms` -- Minkowski sum of a singleton and another set
### Output
`true` iff ``x ∈ ms``.
### Algorithm
Note that ``x ∈ (S ⊕ P)``, where ``S = \\{s\\}`` is a singleton set and
``P`` is a set, if and only if ``(x-s) ∈ P``.
"""
function ∈(x::AbstractVector,
ms::MinkowskiSum{N,S1}) where {N,S1<:AbstractSingleton}
return _in_singleton_msum(x, ms.X, ms.Y)
end
# symmetric method
function ∈(x::AbstractVector,
ms::MinkowskiSum{N,<:LazySet,<:AbstractSingleton}) where {N}
return _in_singleton_msum(x, ms.Y, ms.X)
end
# disambiguation
function ∈(x::AbstractVector,
ms::MinkowskiSum{N,<:AbstractSingleton,<:AbstractSingleton}) where {N}
return _in_singleton_msum(x, ms.X, ms.Y)
end
@inline _in_singleton_msum(x, X, Y) = (x - element(X)) ∈ Y
"""
vertices_list(ms::MinkowskiSum)
Return a list of vertices for the Minkowski sum of two sets.
### Input
- `ms` -- Minkowski sum of two sets
### Output
A list of vertices of the Minkowski sum of two sets.
### Algorithm
We compute the concrete Minkowski sum (via `minkowski_sum`) and call
`vertices_list` on the result.
"""
function vertices_list(ms::MinkowskiSum)
return vertices_list(minkowski_sum(ms.X, ms.Y))
end
function translate(ms::MinkowskiSum, x::AbstractVector)
X = translate(first(ms), x)
Y = translate(second(ms), x)
return MinkowskiSum(X, Y)
end