Skip to content

Commit

Permalink
Merge pull request #332 from JuliaReach/mforets/union_clustering
Browse files Browse the repository at this point in the history
Union clustering
  • Loading branch information
mforets authored Sep 22, 2020
2 parents f43cbba + be5ec35 commit a3e860f
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 3 deletions.
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

0 comments on commit a3e860f

Please sign in to comment.