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

#162 - Add macros to automatically create boilerplate code #228

Merged
merged 10 commits into from
Feb 11, 2018
6 changes: 6 additions & 0 deletions docs/src/lib/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ support_vector
support_function
```

### Other globally defined set functions

```@docs
an_element(S::LazySet{Float64})
```

## Point symmetric set

Point symmetric sets such as balls of different norms are characterized by a
Expand Down
13 changes: 3 additions & 10 deletions docs/src/lib/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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}})
```

Expand All @@ -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}})
```

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions docs/src/lib/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ end

```@docs
sign_cadlag
@neutral
@absorbing
```
130 changes: 35 additions & 95 deletions src/CartesianProduct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -45,9 +49,12 @@ 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
@absorbing(CartesianProduct, EmptySet)

"""
```
*(X::LazySet, Y::LazySet)::CartesianProduct
*(X::LazySet, Y::LazySet)
```

Return the Cartesian product of two convex sets.
Expand All @@ -61,7 +68,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)

"""
×
Expand All @@ -70,43 +77,6 @@ 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} = ∅

"""
dim(cp::CartesianProduct)::Int

Expand Down Expand Up @@ -180,32 +150,34 @@ 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`.

- `CartesianProductArray()` -- constructor for an empty Cartesian product
Constructors:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while we are at this line, a general thought is that i find the illustration of the different constructors to be more friendly if it is given as a proper example, rather than a copy paste of the source code -- if one wants that level of detail, then it's better to just look the code, by clicking on "view source", no? (or use Julia's @edit macro). that is to say that for me we can delete this part and instead put some examples of the different uses (in another PR).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added #232.


- `CartesianProductArray(n::Int, [N]::Type=Float64)`
-- constructor for an empty Cartesian product with size hint and numeric type
- `CartesianProductArray(array::Vector{<:LazySet})` -- default constructor

- `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)
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
Expand All @@ -220,14 +192,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
Expand All @@ -242,52 +216,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,
Copy link
Member

@mforets mforets Feb 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, this change is to save the symbol * for the binary operator only, in other words these two that used to be the same are now different:

julia>  b = Ball2(zeros(2), 1.);

julia> c = CartesianProductArray([b, b])

julia> CartesianProductArray(b, c)
LazySets.CartesianProductArray{Float64,LazySets.Ball2{Float64}}(LazySets.Ball2{Float64}[LazySets.Ball2{Float64}([0.0, 0.0], 1.0), LazySets.Ball2{Float64}([0.0, 0.0], 1.0), LazySets.Ball2{Float64}([0.0, 0.0],
 1.0)])

julia> b * c
LazySets.CartesianProduct{Float64,LazySets.Ball2{Float64},LazySets.CartesianProductArray{Float64,LazySets.Ball2{Float64}}}(LazySets.Ball2{Float64}([0.0, 0.0], 1.0), LazySets.CartesianProductArray{Float64,Laz
ySets.Ball2{Float64}}(LazySets.Ball2{Float64}[LazySets.Ball2{Float64}([0.0, 0.0], 1.0), LazySets.Ball2{Float64}([0.0, 0.0], 1.0), LazySets.Ball2{Float64}([0.0, 0.0], 1.0)]))

i doubt a bit, but maybe it is more sensible the new behavior.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I wanted to discuss this.
Previously * and CartesianProduct were not identical. I found this inconsistent, because *(S, T) was said to be an alias for CartesianProduct(S, T).
Now it is identical, but we get what you observed.

I propose to additionally add a similar macro relating CartesianProduct and CartesianProductArray (and similarly for the other two) such that we also get the old behavior.
If you agree, should I do it here or in a follow-up PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follow-up PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I took a note in the related issue #162.

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
Expand All @@ -302,12 +239,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 CartesianProductArray
@absorbing(CartesianProductArray, EmptySet)

"""
array(cpa::CartesianProductArray{N, S})::Vector{S} where {N<:Real, S<:LazySet{N}}

Expand Down
Loading