From cd5d84289db9465dafc8153595b2b6e6cf9b8887 Mon Sep 17 00:00:00 2001 From: schillic Date: Fri, 16 Dec 2022 19:24:10 +0100 Subject: [PATCH 1/2] fix rand of HParallelotope --- src/Sets/HParallelotope.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Sets/HParallelotope.jl b/src/Sets/HParallelotope.jl index 82a2c198d3..d42c38f13f 100644 --- a/src/Sets/HParallelotope.jl +++ b/src/Sets/HParallelotope.jl @@ -344,6 +344,15 @@ A random parallelotope. ### Notes All numbers are normally distributed with mean 0 and standard deviation 1. + +Technically there is a chance that the resulting set represents an unbounded +set, but this case has not been observed in practice. + +### Algorithm + +The directions matrix and offset vector are created randomly. On average there +is a good chance that this resulting set is empty. We then modify the offset to +ensure non-emptiness. """ function rand(::Type{HParallelotope}; N::Type{<:Real}=Float64, @@ -353,6 +362,13 @@ function rand(::Type{HParallelotope}; rng = reseed(rng, seed) D = randn(rng, N, dim, dim) offset = randn(rng, N, 2 * dim) + + # make sure that the set is not empty: + # `offset[i] >= -offset[i-dim]` for all `i ∈ dim+1:2*dim` + @inbounds for i in dim+1:2*dim + offset[i] = -offset[i-dim] + abs(offset[i]) + end + return HParallelotope(D, offset) end From 7b2f35b3b13b4f3d47f48d4042ad01bee65e873c Mon Sep 17 00:00:00 2001 From: schillic Date: Sun, 19 Feb 2023 23:08:33 +0100 Subject: [PATCH 2/2] let rand of HParallelotope return bounded set --- src/Sets/HParallelotope.jl | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Sets/HParallelotope.jl b/src/Sets/HParallelotope.jl index d42c38f13f..9d48acefba 100644 --- a/src/Sets/HParallelotope.jl +++ b/src/Sets/HParallelotope.jl @@ -345,14 +345,14 @@ A random parallelotope. All numbers are normally distributed with mean 0 and standard deviation 1. -Technically there is a chance that the resulting set represents an unbounded -set, but this case has not been observed in practice. - ### Algorithm The directions matrix and offset vector are created randomly. On average there is a good chance that this resulting set is empty. We then modify the offset to ensure non-emptiness. + +There is a chance that the resulting set represents an unbounded set. This +implementation checks for that case and then samples a new set. """ function rand(::Type{HParallelotope}; N::Type{<:Real}=Float64, @@ -360,16 +360,26 @@ function rand(::Type{HParallelotope}; rng::AbstractRNG=GLOBAL_RNG, seed::Union{Int, Nothing}=nothing) rng = reseed(rng, seed) - D = randn(rng, N, dim, dim) - offset = randn(rng, N, 2 * dim) - # make sure that the set is not empty: - # `offset[i] >= -offset[i-dim]` for all `i ∈ dim+1:2*dim` - @inbounds for i in dim+1:2*dim - offset[i] = -offset[i-dim] + abs(offset[i]) - end + while true + D = randn(rng, N, dim, dim) + offset = randn(rng, N, 2 * dim) - return HParallelotope(D, offset) + # make sure that the set is not empty: + # `offset[i] >= -offset[i-dim]` for all `i ∈ dim+1:2*dim` + @inbounds for i in dim+1:2*dim + offset[i] = -offset[i-dim] + abs(offset[i]) + end + + P = HParallelotope(D, offset) + + # convert to polyhedron to check boundedness + Q = HPolyhedron(vcat(P.directions, -P.directions), P.offset) + if isbounded(Q) + return P + end + # set is unbounded; sample a new set in the next iteration + end end """