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

Union clustering #332

Merged
merged 3 commits into from
Sep 22, 2020
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
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ makedocs(
"API Reference" => Any["Reach-sets" => "lib/reachsets.md",
"Flowpipes" => "lib/flowpipes.md",
"Solutions" => "lib/solutions.md",
"Discretization" => "lib/discretize.md"],
"Discretization" => "lib/discretize.md",
"Clustering" => "lib/clustering.md"],
"References" => "references.md",
"About" => "about.md"
]
Expand Down
44 changes: 44 additions & 0 deletions docs/src/lib/clustering.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
```@meta
DocTestSetup = :(using ReachabilityAnalysis)
CurrentModule = ReachabilityAnalysis
```

# Clustering

## Abstract interface

```@docs
AbstractClusteringMethod
```

## No clustering

```@docs
NoClustering
```

The following methods are available.

## Lazy convexification

```@docs
LazyClustering
```

## Box clustering

```@docs
BoxClustering
```

## Zonotope clustering

```@docs
ZonotopeClustering
```

## Lazy union

```@docs
UnionClustering
```
52 changes: 50 additions & 2 deletions src/Flowpipes/clustering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Abstract supertype for all clustering types, with partition of type `P`.
### Notes

A clustering method defines a function which maps reach-sets to one or several
reach-sets in an over-approximative way, i.e. such that the set union of the input
reach-sets is included in the set union of the output reach-sets.
reach-sets. The mapping can possibly be over-approximative, i.e. such that the
set union of the input reach-sets is included in the set union of the output reach-sets.

By taking the convex hull of the input reach-sets one can reduce the number of
outputs sets to a single one, overapproximately. This is the method that corresponds
Expand Down Expand Up @@ -182,6 +182,14 @@ end
# Zonotope clustering
# =====================================

"""
ZonotopeClustering{P} <: AbstractClusteringMethod{P}

### Notes

This method first takes a lazy convex hull for the given partition, then computes
a zonotope overapproximation of the convex hull.
"""
struct ZonotopeClustering{P} <: AbstractClusteringMethod{P}
partition::P
end
Expand Down Expand Up @@ -210,3 +218,43 @@ end
# convexify and convert to vrep
#C = ReachabilityAnalysis.Convexify(sol[end-aux+1:end])
#Cvertex = convex_hull(vcat([vertices_list(Z) for Z in LazySets.array(set(C))]...)) |> VPolygon

# =====================================
# Lazy union set array clustering
# =====================================

"""
UnionClustering{P} <: AbstractClusteringMethod{P}

Cluster according to the given partition by applying a lazy representation of the
set union.
"""
struct UnionClustering{P} <: AbstractClusteringMethod{P}
partition::P
end

partition(method::UnionClustering) = method.partition

UnionClustering() = UnionClustering(missing)
UnionClustering(nchunks::D) where {D<:Integer} = UnionClustering{D}(nchunks)
UnionClustering(partition::VT) where {D<:Integer, VTi<:AbstractVector{D}, VT<:AbstractVector{VTi}} = UnionClustering{VT}(partition)

function cluster(F, idx, ::UnionClustering{Missing})
Fidx = view(F, idx)
Δt = tspan(Fidx)
Uidx = UnionSetArray([set(R) for R in Fidx])
return [ReachSet(Uidx, Δt)]
end

function cluster(F, idx, method::UnionClustering{P}) where {P}
p = _partition(method, idx)
return [cluster(F, cj, UnionClustering()) for cj in p]
end

# for Taylor model flowpipes we preprocess it with a zonotopic overapproximation
function cluster(F::Flowpipe{N, TaylorModelReachSet{N}}, idx, method::UnionClustering) where {N}
Fz = overapproximate(Flowpipe(view(F, idx)), Zonotope)

# Fx is now indexed from 1 ... length(idx)
return cluster(Fz, 1:length(idx), method)
end
1 change: 1 addition & 0 deletions src/Initialization/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,6 @@ export
# Clustering methods
NoClustering,
LazyClustering,
UnionClustering,
BoxClustering,
ZonotopeClustering
12 changes: 12 additions & 0 deletions test/flowpipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,15 @@ end
@test all(vi ∈ H(ti) for (ti, vi) in zip(times, values))
@test all(vi ∈ H′(ti) for (ti, vi) in zip(times, values))
end

@testset "Flowpipe clustering" begin
X = Interval(0 .. 1)
δ = 0.1
F1 = Flowpipe([ReachSet(X, (0 .. δ) + k*δ) for k in 0:10])

# FIXME requires LazySets#2157
#N = eltype(X)
#U1 = cluster(F1, 8:10, UnionClustering())
#@test U1 isa Vector{ReachSet{N, UnionSetArray{N,Interval{N, IA.Interval{N}}}}}
#@test set(first(U1)) == UnionSetArray([set(Fi) for Fi in F1[8:10]])
end