From f75f6d35b6c437b2e3a9a15777d5d24d1d375baf Mon Sep 17 00:00:00 2001 From: schillic Date: Thu, 8 Feb 2018 20:25:36 +0100 Subject: [PATCH 01/10] add @commutative_neutral macro --- docs/src/lib/utils.md | 1 + src/helper_functions.jl | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/src/lib/utils.md b/docs/src/lib/utils.md index 8b210f6a31..537f5bde49 100644 --- a/docs/src/lib/utils.md +++ b/docs/src/lib/utils.md @@ -9,4 +9,5 @@ end ```@docs sign_cadlag +@commutative_neutral ``` diff --git a/src/helper_functions.jl b/src/helper_functions.jl index 069e011f21..1323a7c616 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -1,6 +1,7 @@ export sign_cadlag, check_method_implementation, - check_method_ambiguity_binary + check_method_ambiguity_binary, + @commutative_neutral """ sign_cadlag(x::N)::N where {N<:Real} @@ -228,3 +229,39 @@ function check_method_ambiguity_binary(op; # result &= !has_other_problems # also report other errors return result end + +""" + @commutative_neutral(SET, NEUT) + +Creates functions to make a set type behave like a commutative monoid. + +### Input + +- `SET` -- set type +- `NEUT` -- set type of the neutral element + +### Output + +Three function definitions. + +### Examples + +`@commutative_neutral(ConvexHull, EmptySet)` creates the following functions: +* `ConvexHull(X::LazySet{N}, ::EmptySet{N}) where {N<:Real} = X` +* `ConvexHull(::EmptySet{N}, X::LazySet{N}) where {N<:Real} = X` +* `ConvexHull(Y::EmptySet{N}, ::EmptySet{N}) where {N<:Real} = Y` +""" +macro commutative_neutral(SET, NEUT) + @eval begin + function $SET(X::LazySet{N}, ::$NEUT{N}) where {N<:Real} + return X + end + function $SET(::$NEUT{N}, X::LazySet{N}) where {N<:Real} + return X + end + function $SET(Y::$NEUT{N}, ::$NEUT{N}) where {N<:Real} + return Y + end + end + return nothing +end From 00df0767a4cb874890cb188278d1ffff446ebe6d Mon Sep 17 00:00:00 2001 From: schillic Date: Thu, 8 Feb 2018 22:18:31 +0100 Subject: [PATCH 02/10] use macro --- src/ConvexHull.jl | 42 +++++------------------------------------- src/MinkowskiSum.jl | 27 ++++----------------------- 2 files changed, 9 insertions(+), 60 deletions(-) diff --git a/src/ConvexHull.jl b/src/ConvexHull.jl index 5c2493fe64..5a706e7a31 100644 --- a/src/ConvexHull.jl +++ b/src/ConvexHull.jl @@ -49,40 +49,8 @@ Alias for `ConvexHull`. """ const CH = ConvexHull -""" - ConvexHull(X, ∅) - -Convex hull of a set with the empty set from the right. - -### Input - -- `X` -- a convex set -- `∅` -- an empty set - -### Output - -The given set because the empty set is neutral for the convex hull. -""" -ConvexHull(X::LazySet{N}, ::EmptySet{N}) where {N<:Real} = X - -""" - ConvexHull(∅, X) - -Convex hull of a set with the empty set from the left. - -### Input - -- `∅` -- an empty set -- `X` -- a convex set - -### Output - -The given set because the empty set is neutral for the convex hull. -""" -ConvexHull(::EmptySet{N}, X::LazySet{N}) where {N<:Real} = X - -# special case: pure empty set convex hull (we require the same numeric type) -(ConvexHull(∅::E, ::E)) where {E<:EmptySet} = ∅ +# EmptySet is the neutral element for ConvexHull +@commutative_neutral(ConvexHull, EmptySet) """ dim(ch::ConvexHull)::Int @@ -158,6 +126,9 @@ function ConvexHullArray(n::Int, N::Type=Float64)::ConvexHullArray return ConvexHullArray(a) end +# EmptySet is the neutral element for ConvexHullArray +@commutative_neutral(ConvexHullArray, EmptySet) + """ CHArray @@ -165,9 +136,6 @@ Alias for `ConvexHullArray`. """ const CHArray = ConvexHullArray -CH(cha::ConvexHullArray, ∅::EmptySet) = cha -CH(∅::EmptySet, cha::ConvexHullArray) = cha - CH(cha1::ConvexHullArray, cha2::ConvexHullArray) = ConvexHullArray(vcat(cha1.array, cha2.array)) """ diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index fe700f901d..ebd663c75b 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -87,12 +87,8 @@ Minkowski sum. # special case: pure empty set Minkowski sum (we require the same numeric type) (+(∅::E, ::E)) where {E<:EmptySet} = ∅ -+(X::LazySet, ::ZeroSet) = X - -+(::ZeroSet, X::LazySet) = X - -# special case: pure zero set Minkowski sum (we require the same numeric type) -(+(X::Z, ::Z)) where {Z<:ZeroSet} = X +# ZeroSet is the neutral element for MinkowskiSum +@commutative_neutral(MinkowskiSum, ZeroSet) """ dim(ms::MinkowskiSum)::Int @@ -230,23 +226,8 @@ function +(msa1::MinkowskiSumArray, msa2::MinkowskiSumArray)::MinkowskiSumArray return msa1 end -""" - +(msa::MinkowskiSumArray, Z::ZeroSet)::MinkowskiSumArray - -Returns the original array because addition with an empty set is a no-op. - -### Input - -- `msa` -- Minkowski sum array -- `Z` -- a Zero set -""" -function +(msa::MinkowskiSumArray, Z::ZeroSet)::MinkowskiSumArray - return msa -end - -function +(Z::ZeroSet, msa::MinkowskiSumArray)::MinkowskiSumArray - return msa -end +# ZeroSet is the neutral element for MinkowskiSum +@commutative_neutral(MinkowskiSumArray, ZeroSet) """ +(msa::MinkowskiSumArray, ∅::EmptySet) From 5ddb0ca38adfe3517b160564fb067871589cb88a Mon Sep 17 00:00:00 2001 From: schillic Date: Thu, 8 Feb 2018 23:00:48 +0100 Subject: [PATCH 03/10] add & use @commutative_absorbing macro --- docs/src/lib/utils.md | 1 + src/CartesianProduct.jl | 105 ++++++++-------------------------------- src/MinkowskiSum.jl | 91 ++++++---------------------------- src/helper_functions.jl | 44 ++++++++++++++++- 4 files changed, 78 insertions(+), 163 deletions(-) diff --git a/docs/src/lib/utils.md b/docs/src/lib/utils.md index 537f5bde49..8b132672e7 100644 --- a/docs/src/lib/utils.md +++ b/docs/src/lib/utils.md @@ -10,4 +10,5 @@ end ```@docs sign_cadlag @commutative_neutral +@commutative_absorbing ``` diff --git a/src/CartesianProduct.jl b/src/CartesianProduct.jl index 9126377fce..2ffcf7874e 100644 --- a/src/CartesianProduct.jl +++ b/src/CartesianProduct.jl @@ -47,7 +47,7 @@ CartesianProduct(Xarr::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = """ ``` - *(X::LazySet, Y::LazySet)::CartesianProduct + *(X::LazySet, Y::LazySet) ``` Return the Cartesian product of two convex sets. @@ -61,7 +61,7 @@ Return the Cartesian product of two convex sets. The Cartesian product of the two convex sets. """ -*(X::LazySet, Y::LazySet)::CartesianProduct = CartesianProduct(X, Y) +*(X::LazySet, Y::LazySet) = CartesianProduct(X, Y) """ × @@ -70,42 +70,8 @@ Alias for the binary Cartesian product. """ ×(X::LazySet, Y::LazySet) = *(X, Y) -""" - X × ∅ - -Right multiplication of a set by an empty set. - -### Input - -- `X` -- a convex set -- `∅` -- an empty set - -### Output - -An empty set, because the empty set is the absorbing element for the -Cartesian product. -""" -*(::LazySet, ∅::EmptySet) = ∅ - -""" - ∅ × X - -Left multiplication of a set by an empty set. - -### Input - -- `X` -- a convex set -- `∅` -- an empty set - -### Output - -An empty set, because the empty set is the absorbing element for the -Cartesian product. -""" -*(∅::EmptySet, ::LazySet) = ∅ - -# special case: pure empty set multiplication (we require the same numeric type) -(*(∅::E, ::E)) where {E<:EmptySet} = ∅ +# EmptySet is the absorbing element for CartesianProduct +@commutative_absorbing(CartesianProduct, EmptySet) """ dim(cp::CartesianProduct)::Int @@ -205,7 +171,8 @@ end """ ``` - *(cpa::CartesianProductArray, S::LazySet)::CartesianProductArray + CartesianProductArray(cpa::CartesianProductArray, + S::LazySet)::CartesianProductArray ``` Multiply a convex set to a Cartesian product of a finite number of convex sets @@ -220,14 +187,16 @@ from the right. The modified Cartesian product of a finite number of convex sets. """ -function *(cpa::CartesianProductArray, S::LazySet)::CartesianProductArray +function CartesianProductArray(cpa::CartesianProductArray, + S::LazySet)::CartesianProductArray push!(cpa.array, S) return cpa end """ ``` - *(S::LazySet, cpa::CartesianProductArray)::CartesianProductArray + CartesianProductArray(S::LazySet, + cpa::CartesianProductArray)::CartesianProductArray ``` Multiply a convex set to a Cartesian product of a finite number of convex sets @@ -242,52 +211,15 @@ from the left. The modified Cartesian product of a finite number of convex sets. """ -function *(S::LazySet, cpa::CartesianProductArray)::CartesianProductArray - push!(cpa.array, S) - return cpa +function CartesianProductArray(S::LazySet, + cpa::CartesianProductArray)::CartesianProductArray + return CartesianProductArray(cpa, S) end """ ``` - *(cpa::CartesianProductArray, ∅::EmptySet) -``` - -Right multiplication of a `CartesianProductArray` by an empty set. - -### Input - -- `cpa` -- Cartesian product array -- `∅` -- an empty set - -### Output - -An empty set, because the empty set is the absorbing element for the -Cartesian product. -""" -*(::CartesianProductArray, ∅::EmptySet) = ∅ - -""" -``` - *(S::EmptySet, cpa::CartesianProductArray) -``` - -Left multiplication of a set by an empty set. - -### Input - -- `X` -- a convex set -- `∅` -- an empty set - -### Output - -An empty set, because the empty set is the absorbing element for the -Cartesian product. -""" -*(∅::EmptySet, ::CartesianProductArray) = ∅ - -""" -``` - *(cpa1::CartesianProductArray, cpa2::CartesianProductArray)::CartesianProductArray + CartesianProductArray(cpa1::CartesianProductArray, + cpa2::CartesianProductArray)::CartesianProductArray ``` Multiply a finite Cartesian product of convex sets to another finite Cartesian @@ -302,12 +234,15 @@ product. The modified first Cartesian product. """ -function *(cpa1::CartesianProductArray, - cpa2::CartesianProductArray)::CartesianProductArray +function CartesianProductArray(cpa1::CartesianProductArray, + cpa2::CartesianProductArray)::CartesianProductArray append!(cpa1.array, cpa2.array) return cpa1 end +# EmptySet is the absorbing element for CartesianProduct +@commutative_absorbing(CartesianProductArray, EmptySet) + """ array(cpa::CartesianProductArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index ebd663c75b..98d938ba3a 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -50,46 +50,12 @@ Unicode alias constructor `\oplus` for the Minkowski sum operator `+(X, Y)`. """ ⊕(X::LazySet, Y::LazySet) = +(X, Y) -""" - X + ∅ - -Right Minkowski sum of a set by an empty set. - -### Input - -- `X` -- a convex set -- `∅` -- an empty set - -### Output - -An empty set, because the empty set is the absorbing element for the -Minkowski sum. -""" -+(::LazySet, ∅::EmptySet) = ∅ - -""" - ∅ + X - -Left Minkowski sum of a set by an empty set. - -### Input - -- `∅` -- an empty set -- `X` -- a convex set - -### Output - -An empty set, because the empty set is the absorbing element for the -Minkowski sum. -""" -+(∅::EmptySet, ::LazySet) = ∅ - -# special case: pure empty set Minkowski sum (we require the same numeric type) -(+(∅::E, ::E)) where {E<:EmptySet} = ∅ - # ZeroSet is the neutral element for MinkowskiSum @commutative_neutral(MinkowskiSum, ZeroSet) +# EmptySet is the absorbing element for MinkowskiSum +@commutative_absorbing(MinkowskiSum, EmptySet) + """ dim(ms::MinkowskiSum)::Int @@ -167,7 +133,7 @@ function MinkowskiSumArray(n::Int, N::Type=Float64)::MinkowskiSumArray end """ - +(msa::MinkowskiSumArray, S::LazySet)::MinkowskiSumArray + MinkowskiSumArray(msa::MinkowskiSumArray, S::LazySet)::MinkowskiSumArray Add a convex set to a Minkowski sum of a finite number of convex sets from the right. @@ -181,13 +147,14 @@ right. The modified Minkowski sum of a finite number of convex sets. """ -function +(msa::MinkowskiSumArray, S::LazySet)::MinkowskiSumArray +function MinkowskiSumArray(msa::MinkowskiSumArray, + S::LazySet)::MinkowskiSumArray push!(msa.array, S) return msa end """ - +(S::LazySet, msa::MinkowskiSumArray)::MinkowskiSumArray + MinkowskiSumArray(S::LazySet, msa::MinkowskiSumArray)::MinkowskiSumArray Add a convex set to a Minkowski sum of a finite number of convex sets from the left. @@ -201,13 +168,15 @@ left. The modified Minkowski sum of a finite number of convex sets. """ -function +(S::LazySet, msa::MinkowskiSumArray)::MinkowskiSumArray +function MinkowskiSumArray(S::LazySet, + msa::MinkowskiSumArray)::MinkowskiSumArray push!(msa.array, S) return msa end """ - +(msa1::MinkowskiSumArray, msa2::MinkowskiSumArray)::MinkowskiSumArray + MinkowskiSumArray(msa1::MinkowskiSumArray, + msa2::MinkowskiSumArray)::MinkowskiSumArray Add the elements of a finite Minkowski sum of convex sets to another finite Minkowski sum. @@ -221,7 +190,8 @@ Minkowski sum. The modified first Minkowski sum of a finite number of convex sets. """ -function +(msa1::MinkowskiSumArray, msa2::MinkowskiSumArray)::MinkowskiSumArray +function MinkowskiSumArray(msa1::MinkowskiSumArray, + msa2::MinkowskiSumArray)::MinkowskiSumArray append!(msa1.array, msa2.array) return msa1 end @@ -229,39 +199,8 @@ end # ZeroSet is the neutral element for MinkowskiSum @commutative_neutral(MinkowskiSumArray, ZeroSet) -""" - +(msa::MinkowskiSumArray, ∅::EmptySet) - -Right Minkowski sum of a set by an empty set. - -### Input - -- `msa` -- Minkowski sum array -- `∅` -- an empty set - -### Output - -An empty set, because the empty set is the absorbing element for the -Minkowski sum. -""" -+(msa::MinkowskiSumArray, ∅::EmptySet) = ∅ - -""" - +(∅::EmptySet, msa::MinkowskiSumArray) - -Left Minkowski sum of a set by an empty set. - -### Input - -- `∅` -- an empty set -- `msa` -- Minkowski sum array - -### Output - -An empty set, because the empty set is the absorbing element for the -Minkowski sum. -""" -+(∅::EmptySet, msa::MinkowskiSumArray) = ∅ +# EmptySet is the absorbing element for MinkowskiSum +@commutative_absorbing(MinkowskiSumArray, EmptySet) """ array(msa::MinkowskiSumArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/helper_functions.jl b/src/helper_functions.jl index 1323a7c616..b356160a9f 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -1,7 +1,8 @@ export sign_cadlag, check_method_implementation, check_method_ambiguity_binary, - @commutative_neutral + @commutative_neutral, + @commutative_absorbing """ sign_cadlag(x::N)::N where {N<:Real} @@ -233,7 +234,8 @@ end """ @commutative_neutral(SET, NEUT) -Creates functions to make a set type behave like a commutative monoid. +Creates functions to make a set type behave commutative with a given neutral +element set type. ### Input @@ -265,3 +267,41 @@ macro commutative_neutral(SET, NEUT) end return nothing end + +""" + @commutative_absorbing(SET, ABS) + +Creates functions to make a set type behave commutative with a given absorbing +element set type. + +### Input + +- `SET` -- set type +- `ABS` -- set type of the absorbing element + +### Output + +Three function definitions. + +### Examples + +`@commutative_absorbing(MinkowskiSum, EmptySet)` creates the following +functions: +* `MinkowskiSum(::LazySet{N}, Y::EmptySet{N}) where {N<:Real} = Y` +* `MinkowskiSum(Y::EmptySet{N}, ::LazySet{N}) where {N<:Real} = Y` +* `MinkowskiSum(Y::EmptySet{N}, ::EmptySet{N}) where {N<:Real} = Y` +""" +macro commutative_absorbing(SET, ABS) + @eval begin + function $SET(::LazySet{N}, Y::$ABS{N}) where {N<:Real} + return Y + end + function $SET(Y::$ABS{N}, ::LazySet{N}) where {N<:Real} + return Y + end + function $SET(Y::$ABS{N}, ::$ABS{N}) where {N<:Real} + return Y + end + end + return nothing +end From 8e9f0b833382e7cc0fd827678a22fcb1c08b949d Mon Sep 17 00:00:00 2001 From: schillic Date: Thu, 8 Feb 2018 23:17:12 +0100 Subject: [PATCH 04/10] add & use @commutative_neutral_absorbing macro --- docs/src/lib/utils.md | 1 + src/MinkowskiSum.jl | 16 ++++++--------- src/helper_functions.jl | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/docs/src/lib/utils.md b/docs/src/lib/utils.md index 8b132672e7..ab94fea695 100644 --- a/docs/src/lib/utils.md +++ b/docs/src/lib/utils.md @@ -11,4 +11,5 @@ end sign_cadlag @commutative_neutral @commutative_absorbing +@commutative_neutral_absorbing ``` diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index 98d938ba3a..f65d84354a 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -50,11 +50,9 @@ Unicode alias constructor `\oplus` for the Minkowski sum operator `+(X, Y)`. """ ⊕(X::LazySet, Y::LazySet) = +(X, Y) -# ZeroSet is the neutral element for MinkowskiSum -@commutative_neutral(MinkowskiSum, ZeroSet) - -# EmptySet is the absorbing element for MinkowskiSum -@commutative_absorbing(MinkowskiSum, EmptySet) +# ZeroSet is the neutral element and EmptySet is the absorbing element for +# MinkowskiSum +@commutative_neutral_absorbing(MinkowskiSum, ZeroSet, EmptySet) """ dim(ms::MinkowskiSum)::Int @@ -196,11 +194,9 @@ function MinkowskiSumArray(msa1::MinkowskiSumArray, return msa1 end -# ZeroSet is the neutral element for MinkowskiSum -@commutative_neutral(MinkowskiSumArray, ZeroSet) - -# EmptySet is the absorbing element for MinkowskiSum -@commutative_absorbing(MinkowskiSumArray, EmptySet) +# ZeroSet is the neutral element and EmptySet is the absorbing element for +# MinkowskiSumArray +@commutative_neutral_absorbing(MinkowskiSumArray, ZeroSet, EmptySet) """ array(msa::MinkowskiSumArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/helper_functions.jl b/src/helper_functions.jl index b356160a9f..cd70472a7d 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -305,3 +305,47 @@ macro commutative_absorbing(SET, ABS) end return nothing end + + +""" + @commutative_neutral_absorbing(SET, NEUT, ABS) + +Creates functions to make a set type behave commutative with both a given +neutral and a given absorbing element set type. + +### Input + +- `SET` -- set type +- `NEUT` -- set type of the neutral element +- `ABS` -- set type of the absorbing element + +### Output + +Eight function definitions. + +### Examples + +`@commutative_neutral_absorbing(MinkowskiSum, ZeroSet, EmptySet))` creates the +following functions: +* `MinkowskiSum(X::LazySet{N}, ::ZeroSet{N}) where {N<:Real} = X` +* `MinkowskiSum(::ZeroSet{N}, X::LazySet{N}) where {N<:Real} = X` +* `MinkowskiSum(Y::ZeroSet{N}, ::ZeroSet{N}) where {N<:Real} = Y` +* `MinkowskiSum(::LazySet{N}, Y::EmptySet{N}) where {N<:Real} = Y` +* `MinkowskiSum(Y::EmptySet{N}, ::LazySet{N}) where {N<:Real} = Y` +* `MinkowskiSum(::ZeroSet{N}, Y::EmptySet{N}) where {N<:Real} = Y` +* `MinkowskiSum(Y::EmptySet{N}, ::ZeroSet{N}) where {N<:Real} = Y` +""" +macro commutative_neutral_absorbing(SET, NEUT, ABS) + @eval begin + @commutative_neutral($SET, $NEUT) + @commutative_absorbing($SET, $ABS) + + function $SET(::$NEUT{N}, Y::$ABS{N}) where {N<:Real} + return Y + end + function $SET(Y::$ABS{N}, ::$NEUT{N}) where {N<:Real} + return Y + end + end + return nothing +end From 9348d4accbe313c0f5cc4957106e6cc59bf779d4 Mon Sep 17 00:00:00 2001 From: schillic Date: Fri, 9 Feb 2018 09:50:01 +0100 Subject: [PATCH 05/10] docs, constructors, restructuring --- src/CartesianProduct.jl | 29 +++++++++++++++++------------ src/ConvexHull.jl | 32 +++++++++++++++++++++++--------- src/MinkowskiSum.jl | 36 +++++++++++++++++++++--------------- 3 files changed, 61 insertions(+), 36 deletions(-) diff --git a/src/CartesianProduct.jl b/src/CartesianProduct.jl index 2ffcf7874e..2f3aa0b2ed 100644 --- a/src/CartesianProduct.jl +++ b/src/CartesianProduct.jl @@ -20,6 +20,10 @@ The Cartesian product of three elements is obtained recursively. See also `CartesianProductArray` for an implementation of a Cartesian product of many sets without recursion, instead using an array. +The `EmptySet` is the absorbing element for `CartesianProduct`. + +Constructors: + - `CartesianProduct{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}}(X1::S1, X2::S2)` -- default constructor @@ -45,6 +49,9 @@ CartesianProduct(Xarr::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = : CartesianProduct(Xarr[1], CartesianProduct(Xarr[2:length(Xarr)]))) +# EmptySet is the absorbing element for CartesianProduct +@commutative_absorbing(CartesianProduct, EmptySet) + """ ``` *(X::LazySet, Y::LazySet) @@ -70,9 +77,6 @@ Alias for the binary Cartesian product. """ ×(X::LazySet, Y::LazySet) = *(X, Y) -# EmptySet is the absorbing element for CartesianProduct -@commutative_absorbing(CartesianProduct, EmptySet) - """ dim(cp::CartesianProduct)::Int @@ -146,24 +150,25 @@ Type that represents the Cartesian product of a finite number of convex sets. ### Notes -- `CartesianProductArray(array::Vector{<:LazySet})` -- default constructor +The `EmptySet` is the absorbing element for `CartesianProductArray`. + +Constructors: -- `CartesianProductArray()` -- constructor for an empty Cartesian product +- `CartesianProductArray(array::Vector{<:LazySet})` -- default constructor -- `CartesianProductArray(n::Int, [N]::Type=Float64)` - -- constructor for an empty Cartesian product with size hint and numeric type +- `CartesianProductArray([n]::Int=0, [N]::Type=Float64)` + -- constructor for an empty product with optional size hint and numeric type """ struct CartesianProductArray{N<:Real, S<:LazySet{N}} <: LazySet{N} array::Vector{S} end + # type-less convenience constructor CartesianProductArray(arr::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = CartesianProductArray{N, S}(arr) -# constructor for an empty Cartesian product of floats -CartesianProductArray() = - CartesianProductArray{Float64, LazySet{Float64}}(Vector{LazySet{Float64}}(0)) -# constructor for an empty Cartesian product with size hint and numeric type -function CartesianProductArray(n::Int, N::Type=Float64)::CartesianProductArray + +# constructor for an empty product with optional size hint and numeric type +function CartesianProductArray(n::Int=0, N::Type=Float64)::CartesianProductArray arr = Vector{LazySet{N}}(0) sizehint!(arr, n) return CartesianProductArray(arr) diff --git a/src/ConvexHull.jl b/src/ConvexHull.jl index 5a706e7a31..5d35aecfc9 100644 --- a/src/ConvexHull.jl +++ b/src/ConvexHull.jl @@ -16,6 +16,10 @@ Type that represents the convex hull of the union of two convex sets. - `X` -- convex set - `Y` -- convex set +### Notes + +The `EmptySet` is the neutral element for `ConvexHull`. + ### Examples Convex hull of two 100-dimensional Euclidean balls: @@ -42,6 +46,9 @@ end ConvexHull(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = ConvexHull{N, S1, S2}(X, Y) +# EmptySet is the neutral element for ConvexHull +@commutative_neutral(ConvexHull, EmptySet) + """ CH @@ -49,9 +56,6 @@ Alias for `ConvexHull`. """ const CH = ConvexHull -# EmptySet is the neutral element for ConvexHull -@commutative_neutral(ConvexHull, EmptySet) - """ dim(ch::ConvexHull)::Int @@ -100,6 +104,17 @@ Type that represents the symbolic convex hull of a finite number of convex sets. - `array` -- array of sets +### Notes + +The `EmptySet` is the neutral element for `ConvexHullArray`. + +Constructors: + +- `ConvexHullArray(array::Vector{<:LazySet})` -- 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 follows a sinusoidal: @@ -113,14 +128,13 @@ julia> c = ConvexHullArray(b); struct ConvexHullArray{N<:Real, S<:LazySet{N}} <: LazySet{N} array::Vector{S} end -# type-less convenience constructor -ConvexHullArray(a::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = ConvexHullArray{N, S}(a) -# constructor for an empty convex hull array -ConvexHullArray() = ConvexHullArray{Float64, LazySet{Float64}}(Vector{LazySet{Float64}}(0)) +# type-less convenience constructor +ConvexHullArray(a::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = + ConvexHullArray{N, S}(a) -# constructor for an empty convex hull array with size hint and numeric type -function ConvexHullArray(n::Int, N::Type=Float64)::ConvexHullArray +# constructor for an empty hull with optional size hint and numeric type +function ConvexHullArray(n::Int=0, N::Type=Float64)::ConvexHullArray a = Vector{LazySet{N}}(0) sizehint!(a, n) return ConvexHullArray(a) diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index f65d84354a..b914f72b6b 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -13,6 +13,11 @@ Type that represents the Minkowski sum of two convex sets. - `X` -- first convex set - `Y` -- second convex set + +### Notes + +The `ZeroSet` is the neutral element and the `EmptySet` is the absorbing element +for `MinkowskiSum`. """ struct MinkowskiSum{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N} X::S1 @@ -27,6 +32,10 @@ end MinkowskiSum(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = MinkowskiSum{N, S1, S2}(X, Y) +# ZeroSet is the neutral element and EmptySet is the absorbing element for +# MinkowskiSum +@commutative_neutral_absorbing(MinkowskiSum, ZeroSet, EmptySet) + """ X + Y @@ -50,10 +59,6 @@ Unicode alias constructor `\oplus` for the Minkowski sum operator `+(X, Y)`. """ ⊕(X::LazySet, Y::LazySet) = +(X, Y) -# ZeroSet is the neutral element and EmptySet is the absorbing element for -# MinkowskiSum -@commutative_neutral_absorbing(MinkowskiSum, ZeroSet, EmptySet) - """ dim(ms::MinkowskiSum)::Int @@ -107,24 +112,26 @@ Type that represents the Minkowski sum of a finite number of convex sets. This type assumes that the dimensions of all elements match. -- `MinkowskiSumArray(array::Vector{<:LazySet})` -- default constructor +The `ZeroSet` is the neutral element and the `EmptySet` is the absorbing element +for `MinkowskiSumArray`. -- `MinkowskiSumArray()` -- constructor for an empty sum +Constructors: + +- `MinkowskiSumArray(array::Vector{<:LazySet})` -- default constructor -- `MinkowskiSumArray(n::Int, [N]::Type=Float64)` - -- constructor for an empty sum with size hint and numeric type +- `MinkowskiSumArray([n]::Int=0, [N]::Type=Float64)` + -- constructor for an empty sum with optional size hint and numeric type """ struct MinkowskiSumArray{N<:Real, S<:LazySet{N}} <: LazySet{N} array::Vector{S} end + # type-less convenience constructor MinkowskiSumArray(arr::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = MinkowskiSumArray{N, S}(arr) -# constructor for an empty sum of float type -MinkowskiSumArray() = - MinkowskiSumArray{Float64, LazySet{Float64}}(Vector{LazySet{Float64}}(0)) -# constructor for an empty sum with size hint and numeric type -function MinkowskiSumArray(n::Int, N::Type=Float64)::MinkowskiSumArray + +# constructor for an empty sum with optional size hint and numeric type +function MinkowskiSumArray(n::Int=0, N::Type=Float64)::MinkowskiSumArray arr = Vector{LazySet{N}}(0) sizehint!(arr, n) return MinkowskiSumArray(arr) @@ -168,8 +175,7 @@ The modified Minkowski sum of a finite number of convex sets. """ function MinkowskiSumArray(S::LazySet, msa::MinkowskiSumArray)::MinkowskiSumArray - push!(msa.array, S) - return msa + return MinkowskiSumArray(msa, S) end """ From 714a8eb3ac52c4229f724a6cfcf950b5a912adc7 Mon Sep 17 00:00:00 2001 From: schillic Date: Fri, 9 Feb 2018 09:54:05 +0100 Subject: [PATCH 06/10] MinkowskiSum unit tests for neutral/absorbing element --- test/unit_MinkowskiSum.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/unit_MinkowskiSum.jl b/test/unit_MinkowskiSum.jl index 69ce327d44..87805fd963 100644 --- a/test/unit_MinkowskiSum.jl +++ b/test/unit_MinkowskiSum.jl @@ -53,4 +53,12 @@ for N in [Float64, Rational{Int}, Float32] # array getter v = Vector{N}(0) @test array(MinkowskiSumArray()) == v + + # neutral and absorbing element + z = ZeroSet{N}(2) + e = EmptySet{N}() + b = BallInf(N[0., 0.], N(2.)) + @test b + z == z + b == b + @test b + e == e + b == e + e == e + @test z + e == e + z == e end From 76da433d1507d50dbc6c7bf2705444931f644fa8 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 10 Feb 2018 19:44:32 +0100 Subject: [PATCH 07/10] review: do not export, docs --- src/helper_functions.jl | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/helper_functions.jl b/src/helper_functions.jl index cd70472a7d..aabfa761d5 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -1,8 +1,6 @@ export sign_cadlag, check_method_implementation, - check_method_ambiguity_binary, - @commutative_neutral, - @commutative_absorbing + check_method_ambiguity_binary """ sign_cadlag(x::N)::N where {N<:Real} @@ -248,10 +246,10 @@ Three function definitions. ### Examples -`@commutative_neutral(ConvexHull, EmptySet)` creates the following functions: -* `ConvexHull(X::LazySet{N}, ::EmptySet{N}) where {N<:Real} = X` -* `ConvexHull(::EmptySet{N}, X::LazySet{N}) where {N<:Real} = X` -* `ConvexHull(Y::EmptySet{N}, ::EmptySet{N}) where {N<:Real} = Y` +`@commutative_neutral(ConvexHull, N)` creates the following functions: +* `ConvexHull(X, N) = X` +* `ConvexHull(N, X) = X` +* `ConvexHull(N, N) = N` """ macro commutative_neutral(SET, NEUT) @eval begin @@ -285,11 +283,10 @@ Three function definitions. ### Examples -`@commutative_absorbing(MinkowskiSum, EmptySet)` creates the following -functions: -* `MinkowskiSum(::LazySet{N}, Y::EmptySet{N}) where {N<:Real} = Y` -* `MinkowskiSum(Y::EmptySet{N}, ::LazySet{N}) where {N<:Real} = Y` -* `MinkowskiSum(Y::EmptySet{N}, ::EmptySet{N}) where {N<:Real} = Y` +`@commutative_absorbing(ConvexHull, A)` creates the following functions: +* `ConvexHull(X, A) = A` +* `ConvexHull(A, X) = A` +* `ConvexHull(A, A) = A` """ macro commutative_absorbing(SET, ABS) @eval begin @@ -325,15 +322,16 @@ Eight function definitions. ### Examples -`@commutative_neutral_absorbing(MinkowskiSum, ZeroSet, EmptySet))` creates the -following functions: -* `MinkowskiSum(X::LazySet{N}, ::ZeroSet{N}) where {N<:Real} = X` -* `MinkowskiSum(::ZeroSet{N}, X::LazySet{N}) where {N<:Real} = X` -* `MinkowskiSum(Y::ZeroSet{N}, ::ZeroSet{N}) where {N<:Real} = Y` -* `MinkowskiSum(::LazySet{N}, Y::EmptySet{N}) where {N<:Real} = Y` -* `MinkowskiSum(Y::EmptySet{N}, ::LazySet{N}) where {N<:Real} = Y` -* `MinkowskiSum(::ZeroSet{N}, Y::EmptySet{N}) where {N<:Real} = Y` -* `MinkowskiSum(Y::EmptySet{N}, ::ZeroSet{N}) where {N<:Real} = Y` +`@commutative_neutral_absorbing(ConvexHull, N, A)` creates the following +functions: +* `ConvexHull(X, N) = X` +* `ConvexHull(N, X) = X` +* `ConvexHull(N, N) = N` +* `ConvexHull(X, A) = A` +* `ConvexHull(A, X) = A` +* `ConvexHull(A, A) = A` +* `ConvexHull(N, A) = A` +* `ConvexHull(A, N) = A` """ macro commutative_neutral_absorbing(SET, NEUT, ABS) @eval begin From 345fc2446cff2b7282c794ba5bc561efce1dad91 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 10 Feb 2018 20:15:46 +0100 Subject: [PATCH 08/10] add neutral/absorbing function and unify macros --- src/CartesianProduct.jl | 12 +++- src/ConvexHull.jl | 10 +++- src/LazySet.jl | 39 ++++++++++++- src/MinkowskiSum.jl | 22 +++++-- src/helper_functions.jl | 125 +++++++++++++--------------------------- 5 files changed, 110 insertions(+), 98 deletions(-) diff --git a/src/CartesianProduct.jl b/src/CartesianProduct.jl index 2f3aa0b2ed..fea47f62f5 100644 --- a/src/CartesianProduct.jl +++ b/src/CartesianProduct.jl @@ -50,7 +50,10 @@ CartesianProduct(Xarr::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = CartesianProduct(Xarr[2:length(Xarr)]))) # EmptySet is the absorbing element for CartesianProduct -@commutative_absorbing(CartesianProduct, EmptySet) +absorbing(::Type{CartesianProduct}) = EmptySet + +# create absorbing element functions +@commutative_neutral_absorbing(CartesianProduct) """ ``` @@ -245,8 +248,11 @@ function CartesianProductArray(cpa1::CartesianProductArray, return cpa1 end -# EmptySet is the absorbing element for CartesianProduct -@commutative_absorbing(CartesianProductArray, EmptySet) +# EmptySet is the absorbing element for CartesianProductArray +absorbing(::Type{CartesianProductArray}) = EmptySet + +# create absorbing element functions +@commutative_neutral_absorbing(CartesianProductArray) """ array(cpa::CartesianProductArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/ConvexHull.jl b/src/ConvexHull.jl index 5d35aecfc9..f306d789e1 100644 --- a/src/ConvexHull.jl +++ b/src/ConvexHull.jl @@ -47,7 +47,10 @@ ConvexHull(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} ConvexHull{N, S1, S2}(X, Y) # EmptySet is the neutral element for ConvexHull -@commutative_neutral(ConvexHull, EmptySet) +neutral(::Type{ConvexHull}) = EmptySet + +# create neutral element functions +@commutative_neutral_absorbing(ConvexHull) """ CH @@ -141,7 +144,10 @@ function ConvexHullArray(n::Int=0, N::Type=Float64)::ConvexHullArray end # EmptySet is the neutral element for ConvexHullArray -@commutative_neutral(ConvexHullArray, EmptySet) +neutral(::Type{ConvexHullArray}) = EmptySet + +# create neutral element functions +@commutative_neutral_absorbing(ConvexHullArray) """ CHArray diff --git a/src/LazySet.jl b/src/LazySet.jl index bb5debb3b4..80d67b7d5b 100644 --- a/src/LazySet.jl +++ b/src/LazySet.jl @@ -7,7 +7,9 @@ export LazySet, norm, radius, diameter, - an_element + an_element, + neutral, + absorbing """ LazySet{N} @@ -182,3 +184,38 @@ An element of a convex set. function an_element(S::LazySet{N})::AbstractVector{N} where {N<:Real} return σ(sparsevec([1], [one(N)], dim(S)), S) end + + +""" + neutral(S::Type{<:LazySet}) + +Returns the neutral element for a set operation. + +### Input + +- `S` -- a set operation + +### Output + +The neutral element type, or `nothing` by default. +""" +function neutral(S::Type{<:LazySet}) + return nothing +end + +""" + absorbing(S::Type{<:LazySet}) + +Returns the absorbing element for a set operation. + +### Input + +- `S` -- a set operation + +### Output + +The absorbing element type, or `nothing` by default. +""" +function absorbing(S::Type{<:LazySet}) + return nothing +end diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index b914f72b6b..ff2c621c97 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -32,9 +32,14 @@ end MinkowskiSum(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = MinkowskiSum{N, S1, S2}(X, Y) -# ZeroSet is the neutral element and EmptySet is the absorbing element for -# MinkowskiSum -@commutative_neutral_absorbing(MinkowskiSum, ZeroSet, EmptySet) +# ZeroSet is the neutral element for MinkowskiSum +neutral(::Type{MinkowskiSum}) = ZeroSet + +# EmptySet is the absorbing element for MinkowskiSum +absorbing(::Type{MinkowskiSum}) = EmptySet + +# create neutral/absorbing element functions +@commutative_neutral_absorbing(MinkowskiSum) """ X + Y @@ -200,9 +205,14 @@ function MinkowskiSumArray(msa1::MinkowskiSumArray, return msa1 end -# ZeroSet is the neutral element and EmptySet is the absorbing element for -# MinkowskiSumArray -@commutative_neutral_absorbing(MinkowskiSumArray, ZeroSet, EmptySet) +# ZeroSet is the neutral element for MinkowskiSumArray +neutral(::Type{MinkowskiSumArray}) = ZeroSet + +# EmptySet is the absorbing element for MinkowskiSumArray +absorbing(::Type{MinkowskiSumArray}) = EmptySet + +# create neutral element functions +@commutative_neutral_absorbing(MinkowskiSumArray) """ array(msa::MinkowskiSumArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/helper_functions.jl b/src/helper_functions.jl index aabfa761d5..39ca1b19a6 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -230,82 +230,7 @@ function check_method_ambiguity_binary(op; end """ - @commutative_neutral(SET, NEUT) - -Creates functions to make a set type behave commutative with a given neutral -element set type. - -### Input - -- `SET` -- set type -- `NEUT` -- set type of the neutral element - -### Output - -Three function definitions. - -### Examples - -`@commutative_neutral(ConvexHull, N)` creates the following functions: -* `ConvexHull(X, N) = X` -* `ConvexHull(N, X) = X` -* `ConvexHull(N, N) = N` -""" -macro commutative_neutral(SET, NEUT) - @eval begin - function $SET(X::LazySet{N}, ::$NEUT{N}) where {N<:Real} - return X - end - function $SET(::$NEUT{N}, X::LazySet{N}) where {N<:Real} - return X - end - function $SET(Y::$NEUT{N}, ::$NEUT{N}) where {N<:Real} - return Y - end - end - return nothing -end - -""" - @commutative_absorbing(SET, ABS) - -Creates functions to make a set type behave commutative with a given absorbing -element set type. - -### Input - -- `SET` -- set type -- `ABS` -- set type of the absorbing element - -### Output - -Three function definitions. - -### Examples - -`@commutative_absorbing(ConvexHull, A)` creates the following functions: -* `ConvexHull(X, A) = A` -* `ConvexHull(A, X) = A` -* `ConvexHull(A, A) = A` -""" -macro commutative_absorbing(SET, ABS) - @eval begin - function $SET(::LazySet{N}, Y::$ABS{N}) where {N<:Real} - return Y - end - function $SET(Y::$ABS{N}, ::LazySet{N}) where {N<:Real} - return Y - end - function $SET(Y::$ABS{N}, ::$ABS{N}) where {N<:Real} - return Y - end - end - return nothing -end - - -""" - @commutative_neutral_absorbing(SET, NEUT, ABS) + @commutative_neutral_absorbing(SET) Creates functions to make a set type behave commutative with both a given neutral and a given absorbing element set type. @@ -313,12 +238,15 @@ neutral and a given absorbing element set type. ### Input - `SET` -- set type -- `NEUT` -- set type of the neutral element -- `ABS` -- set type of the absorbing element ### Output -Eight function definitions. +Up to eight function definitions. + +### Notes + +In order to use a neutral and/or absorbing element, the function `neutral` resp. +`absorbing` must be overridden for the given `SET` type in advance. ### Examples @@ -333,16 +261,41 @@ functions: * `ConvexHull(N, A) = A` * `ConvexHull(A, N) = A` """ -macro commutative_neutral_absorbing(SET, NEUT, ABS) +macro commutative_neutral_absorbing(SET) @eval begin - @commutative_neutral($SET, $NEUT) - @commutative_absorbing($SET, $ABS) + neutral_el = neutral($SET) + if neutral_el != nothing + function $SET(X::LazySet{N}, ::neutral_el{N}) where {N<:Real} + return X + end + function $SET(::neutral_el{N}, X::LazySet{N}) where {N<:Real} + return X + end + function $SET(Y::neutral_el{N}, ::neutral_el{N}) where {N<:Real} + return Y + end + end - function $SET(::$NEUT{N}, Y::$ABS{N}) where {N<:Real} - return Y + absorbing_el = absorbing($SET) + if absorbing_el != nothing + function $SET(::LazySet{N}, Y::absorbing_el{N}) where {N<:Real} + return Y + end + function $SET(Y::absorbing_el{N}, ::LazySet{N}) where {N<:Real} + return Y + end + function $SET(Y::absorbing_el{N}, ::absorbing_el{N}) where {N<:Real} + return Y + end end - function $SET(Y::$ABS{N}, ::$NEUT{N}) where {N<:Real} - return Y + + if neutral_el != nothing && absorbing_el != nothing + function $SET(::neutral_el{N}, Y::absorbing_el{N}) where {N<:Real} + return Y + end + function $SET(Y::absorbing_el{N}, ::neutral_el{N}) where {N<:Real} + return Y + end end end return nothing From b85d1e44c9d09d385101d1803b01a80b75864080 Mon Sep 17 00:00:00 2001 From: schillic Date: Sat, 10 Feb 2018 20:26:00 +0100 Subject: [PATCH 09/10] fix docs --- docs/src/lib/interfaces.md | 8 ++++++++ docs/src/lib/operations.md | 13 +++---------- docs/src/lib/utils.md | 2 -- src/helper_functions.jl | 18 +++++++++--------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/src/lib/interfaces.md b/docs/src/lib/interfaces.md index 5a45d2cede..57842dd305 100644 --- a/docs/src/lib/interfaces.md +++ b/docs/src/lib/interfaces.md @@ -48,6 +48,14 @@ support_vector support_function ``` +### Other globally defined set functions + +```@docs +neutral(::Type{<:LazySet}) +absorbing(::Type{<:LazySet}) +an_element(S::LazySet{Float64}) +``` + ## Point symmetric set Point symmetric sets such as balls of different norms are characterized by a diff --git a/docs/src/lib/operations.md b/docs/src/lib/operations.md index 9b9c2c0ab9..5421fd9394 100644 --- a/docs/src/lib/operations.md +++ b/docs/src/lib/operations.md @@ -21,9 +21,9 @@ end ```@docs CartesianProduct +Base.:*(::LazySet{Float64}, ::LazySet{Float64}) dim(::CartesianProduct{Float64, LazySet{Float64}, LazySet{Float64}}) σ(::AbstractVector{Float64}, ::CartesianProduct{Float64, LazySet{Float64}, LazySet{Float64}}) -Base.:*(::LazySet{Float64}, ::LazySet{Float64}) ∈(::AbstractVector{Float64}, ::CartesianProduct{Float64, LazySet{Float64}, LazySet{Float64}}) ``` @@ -34,9 +34,6 @@ CartesianProductArray{Float64, LazySet{Float64}} array(::CartesianProductArray{Float64, LazySet{Float64}}) dim(::CartesianProductArray{Float64, LazySet{Float64}}) σ(::AbstractVector{Float64}, ::CartesianProductArray{Float64, LazySet{Float64}}) -Base.:*(::CartesianProductArray{Float64, LazySet{Float64}}, ::LazySet{Float64}) -Base.:*(::LazySet{Float64}, ::CartesianProductArray{Float64, LazySet{Float64}}) -Base.:*(::CartesianProductArray{Float64, LazySet{Float64}}, ::CartesianProductArray{Float64, LazySet{Float64}}) ∈(::AbstractVector{Float64}, ::CartesianProductArray{Float64, LazySet{Float64}}) ``` @@ -86,10 +83,10 @@ isempty(::Intersection{Float64, LazySet{Float64}, LazySet{Float64}}) ```@docs MinkowskiSum -dim(::MinkowskiSum{Float64, LazySet{Float64}, LazySet{Float64}}) -σ(::AbstractVector{Float64}, ::MinkowskiSum{Float64, LazySet{Float64}, LazySet{Float64}}) Base.:+(::LazySet{Float64}, ::LazySet{Float64}) ⊕ +dim(::MinkowskiSum{Float64, LazySet{Float64}, LazySet{Float64}}) +σ(::AbstractVector{Float64}, ::MinkowskiSum{Float64, LazySet{Float64}, LazySet{Float64}}) ``` ### ``n``-ary Minkowski Sum @@ -99,10 +96,6 @@ MinkowskiSumArray array(::MinkowskiSumArray{Float64, LazySet{Float64}}) dim(::MinkowskiSumArray{Float64, LazySet{Float64}}) σ(::AbstractVector{Float64}, ::MinkowskiSumArray{Float64, LazySet{Float64}}) -Base.:+(::MinkowskiSumArray{Float64, LazySet{Float64}}, ::LazySet{Float64}) -Base.:+(::LazySet{Float64}, ::MinkowskiSumArray{Float64, LazySet{Float64}}) -Base.:+(::MinkowskiSumArray{Float64, LazySet{Float64}}, ::MinkowskiSumArray{Float64, LazySet{Float64}}) -Base.:+(::MinkowskiSumArray{Float64, LazySet{Float64}}, ::ZeroSet{Float64}) ``` ## Maps diff --git a/docs/src/lib/utils.md b/docs/src/lib/utils.md index ab94fea695..e4d439dd87 100644 --- a/docs/src/lib/utils.md +++ b/docs/src/lib/utils.md @@ -9,7 +9,5 @@ end ```@docs sign_cadlag -@commutative_neutral -@commutative_absorbing @commutative_neutral_absorbing ``` diff --git a/src/helper_functions.jl b/src/helper_functions.jl index 39ca1b19a6..16d460dae6 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -250,16 +250,16 @@ In order to use a neutral and/or absorbing element, the function `neutral` resp. ### Examples -`@commutative_neutral_absorbing(ConvexHull, N, A)` creates the following +`@commutative_neutral_absorbing(MinkowskiSum, N, A)` creates the following functions: -* `ConvexHull(X, N) = X` -* `ConvexHull(N, X) = X` -* `ConvexHull(N, N) = N` -* `ConvexHull(X, A) = A` -* `ConvexHull(A, X) = A` -* `ConvexHull(A, A) = A` -* `ConvexHull(N, A) = A` -* `ConvexHull(A, N) = A` +* `MinkowskiSum(X, N) = X` +* `MinkowskiSum(N, X) = X` +* `MinkowskiSum(N, N) = N` +* `MinkowskiSum(X, A) = A` +* `MinkowskiSum(A, X) = A` +* `MinkowskiSum(A, A) = A` +* `MinkowskiSum(N, A) = A` +* `MinkowskiSum(A, N) = A` """ macro commutative_neutral_absorbing(SET) @eval begin From c69313d00b76b25771a523e3ebdb5aa005e64c0b Mon Sep 17 00:00:00 2001 From: schillic Date: Sun, 11 Feb 2018 14:31:53 +0100 Subject: [PATCH 10/10] new @neutral and @absorbing macros --- docs/src/lib/interfaces.md | 2 - docs/src/lib/utils.md | 3 +- src/CartesianProduct.jl | 10 +--- src/ConvexHull.jl | 10 +--- src/LazySet.jl | 35 ----------- src/MinkowskiSum.jl | 14 ++--- src/helper_functions.jl | 116 +++++++++++++++++++++++++------------ 7 files changed, 90 insertions(+), 100 deletions(-) diff --git a/docs/src/lib/interfaces.md b/docs/src/lib/interfaces.md index 57842dd305..88e02f4d99 100644 --- a/docs/src/lib/interfaces.md +++ b/docs/src/lib/interfaces.md @@ -51,8 +51,6 @@ support_function ### Other globally defined set functions ```@docs -neutral(::Type{<:LazySet}) -absorbing(::Type{<:LazySet}) an_element(S::LazySet{Float64}) ``` diff --git a/docs/src/lib/utils.md b/docs/src/lib/utils.md index e4d439dd87..1ed56f9c66 100644 --- a/docs/src/lib/utils.md +++ b/docs/src/lib/utils.md @@ -9,5 +9,6 @@ end ```@docs sign_cadlag -@commutative_neutral_absorbing +@neutral +@absorbing ``` diff --git a/src/CartesianProduct.jl b/src/CartesianProduct.jl index fea47f62f5..387abae1e1 100644 --- a/src/CartesianProduct.jl +++ b/src/CartesianProduct.jl @@ -50,10 +50,7 @@ CartesianProduct(Xarr::Vector{S}) where {S<:LazySet{N}} where {N<:Real} = CartesianProduct(Xarr[2:length(Xarr)]))) # EmptySet is the absorbing element for CartesianProduct -absorbing(::Type{CartesianProduct}) = EmptySet - -# create absorbing element functions -@commutative_neutral_absorbing(CartesianProduct) +@absorbing(CartesianProduct, EmptySet) """ ``` @@ -249,10 +246,7 @@ function CartesianProductArray(cpa1::CartesianProductArray, end # EmptySet is the absorbing element for CartesianProductArray -absorbing(::Type{CartesianProductArray}) = EmptySet - -# create absorbing element functions -@commutative_neutral_absorbing(CartesianProductArray) +@absorbing(CartesianProductArray, EmptySet) """ array(cpa::CartesianProductArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/ConvexHull.jl b/src/ConvexHull.jl index f306d789e1..9a9790cfdd 100644 --- a/src/ConvexHull.jl +++ b/src/ConvexHull.jl @@ -47,10 +47,7 @@ ConvexHull(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} ConvexHull{N, S1, S2}(X, Y) # EmptySet is the neutral element for ConvexHull -neutral(::Type{ConvexHull}) = EmptySet - -# create neutral element functions -@commutative_neutral_absorbing(ConvexHull) +@neutral(ConvexHull, EmptySet) """ CH @@ -144,10 +141,7 @@ function ConvexHullArray(n::Int=0, N::Type=Float64)::ConvexHullArray end # EmptySet is the neutral element for ConvexHullArray -neutral(::Type{ConvexHullArray}) = EmptySet - -# create neutral element functions -@commutative_neutral_absorbing(ConvexHullArray) +@neutral(ConvexHullArray, EmptySet) """ CHArray diff --git a/src/LazySet.jl b/src/LazySet.jl index 80d67b7d5b..111d6b59cf 100644 --- a/src/LazySet.jl +++ b/src/LazySet.jl @@ -184,38 +184,3 @@ An element of a convex set. function an_element(S::LazySet{N})::AbstractVector{N} where {N<:Real} return σ(sparsevec([1], [one(N)], dim(S)), S) end - - -""" - neutral(S::Type{<:LazySet}) - -Returns the neutral element for a set operation. - -### Input - -- `S` -- a set operation - -### Output - -The neutral element type, or `nothing` by default. -""" -function neutral(S::Type{<:LazySet}) - return nothing -end - -""" - absorbing(S::Type{<:LazySet}) - -Returns the absorbing element for a set operation. - -### Input - -- `S` -- a set operation - -### Output - -The absorbing element type, or `nothing` by default. -""" -function absorbing(S::Type{<:LazySet}) - return nothing -end diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index ff2c621c97..69378a8fe4 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -33,13 +33,10 @@ MinkowskiSum(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real MinkowskiSum{N, S1, S2}(X, Y) # ZeroSet is the neutral element for MinkowskiSum -neutral(::Type{MinkowskiSum}) = ZeroSet +@neutral(MinkowskiSum, ZeroSet) # EmptySet is the absorbing element for MinkowskiSum -absorbing(::Type{MinkowskiSum}) = EmptySet - -# create neutral/absorbing element functions -@commutative_neutral_absorbing(MinkowskiSum) +@absorbing(MinkowskiSum, EmptySet) """ X + Y @@ -206,13 +203,10 @@ function MinkowskiSumArray(msa1::MinkowskiSumArray, end # ZeroSet is the neutral element for MinkowskiSumArray -neutral(::Type{MinkowskiSumArray}) = ZeroSet +@neutral(MinkowskiSumArray, ZeroSet) # EmptySet is the absorbing element for MinkowskiSumArray -absorbing(::Type{MinkowskiSumArray}) = EmptySet - -# create neutral element functions -@commutative_neutral_absorbing(MinkowskiSumArray) +@absorbing(MinkowskiSumArray, EmptySet) """ array(msa::MinkowskiSumArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}} diff --git a/src/helper_functions.jl b/src/helper_functions.jl index 16d460dae6..56ed31d293 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -230,70 +230,114 @@ function check_method_ambiguity_binary(op; end """ - @commutative_neutral_absorbing(SET) + @neutral(SET, NEUT) -Creates functions to make a set type behave commutative with both a given -neutral and a given absorbing element set type. +Creates functions to make a set type behave commutative with a given neutral +element set type. ### Input -- `SET` -- set type +- `SET` -- set type ### Output -Up to eight function definitions. +Nothing. ### Notes -In order to use a neutral and/or absorbing element, the function `neutral` resp. -`absorbing` must be overridden for the given `SET` type in advance. +This macro generates three functions (and possibly two more if `@absorbing` has +been used in advance). ### Examples -`@commutative_neutral_absorbing(MinkowskiSum, N, A)` creates the following -functions: +`@neutral(MinkowskiSum, N)` creates the following functions: * `MinkowskiSum(X, N) = X` * `MinkowskiSum(N, X) = X` * `MinkowskiSum(N, N) = N` -* `MinkowskiSum(X, A) = A` -* `MinkowskiSum(A, X) = A` -* `MinkowskiSum(A, A) = A` -* `MinkowskiSum(N, A) = A` -* `MinkowskiSum(A, N) = A` """ -macro commutative_neutral_absorbing(SET) +macro neutral(SET, NEUT) @eval begin - neutral_el = neutral($SET) - if neutral_el != nothing - function $SET(X::LazySet{N}, ::neutral_el{N}) where {N<:Real} - return X - end - function $SET(::neutral_el{N}, X::LazySet{N}) where {N<:Real} - return X - end - function $SET(Y::neutral_el{N}, ::neutral_el{N}) where {N<:Real} - return Y - end + # create function to obtain the neutral element + function neutral(::Type{$SET}) + return $NEUT end - absorbing_el = absorbing($SET) - if absorbing_el != nothing - function $SET(::LazySet{N}, Y::absorbing_el{N}) where {N<:Real} - return Y - end - function $SET(Y::absorbing_el{N}, ::LazySet{N}) where {N<:Real} + # create functions to declare the neutral element + function $SET(X::LazySet{N}, ::$NEUT{N}) where {N<:Real} + return X + end + function $SET(::$NEUT{N}, X::LazySet{N}) where {N<:Real} + return X + end + function $SET(Y::$NEUT{N}, ::$NEUT{N}) where {N<:Real} + return Y + end + + # if the absorbing element has already been defined, create combinations + if isdefined(:absorbing) && method_exists(absorbing, (Type{$SET},)) + ABS = absorbing($SET) + function $SET(::$NEUT{N}, Y::ABS{N}) where {N<:Real} return Y end - function $SET(Y::absorbing_el{N}, ::absorbing_el{N}) where {N<:Real} + function $SET(Y::ABS{N}, ::$NEUT{N}) where {N<:Real} return Y end end + end + return nothing +end + +""" + @absorbing(SET, ABS) + +Creates functions to make a set type behave commutative with a given absorbing +element set type. + +### Input + +- `SET` -- set type + +### Output + +Nothing. + +### Notes + +This macro generates three functions (and possibly two more if `@absorbing` has +been used in advance). + +### Examples + +`@absorbing(MinkowskiSum, A)` creates the following functions: +* `MinkowskiSum(X, A) = A` +* `MinkowskiSum(A, X) = A` +* `MinkowskiSum(A, A) = A` +""" +macro absorbing(SET, ABS) + @eval begin + # create function to obtain the absorbing element + function absorbing(::Type{$SET}) + return $ABS + end + + # create functions to declare the absorbing element + function $SET(::LazySet{N}, Y::$ABS{N}) where {N<:Real} + return Y + end + function $SET(Y::$ABS{N}, ::LazySet{N}) where {N<:Real} + return Y + end + function $SET(Y::$ABS{N}, ::$ABS{N}) where {N<:Real} + return Y + end - if neutral_el != nothing && absorbing_el != nothing - function $SET(::neutral_el{N}, Y::absorbing_el{N}) where {N<:Real} + # if the neutral element has already been defined, create combinations + if isdefined(:neutral) && method_exists(neutral, (Type{$SET},)) + NEUT = neutral($SET) + function $SET(::NEUT{N}, Y::$ABS{N}) where {N<:Real} return Y end - function $SET(Y::absorbing_el{N}, ::neutral_el{N}) where {N<:Real} + function $SET(Y::$ABS{N}, ::NEUT{N}) where {N<:Real} return Y end end