Utilities

Macros

LazySets.@neutralMacro
@neutral(SET, NEUT)

Create methods to make a lazy set operation commutative with a given neutral-element set type.

Input

  • SET – set type of lazy operation
  • NEUT – set type of neutral element

Output

Nothing.

Notes

This macro generates four functions (possibly two more if @absorbing has been used in advance, and possibly two or four more if @declare_array_version has been used in advance).

Examples

@neutral(MinkowskiSum, N) creates at least the following methods:

  • neutral(::MinkowskiSum) = N
  • MinkowskiSum(X, N) = X
  • MinkowskiSum(N, X) = X
  • MinkowskiSum(N, N) = N
source
LazySets.@absorbingMacro
@absorbing(SET, ABS)

Create methods to make a lazy set operation commutative with a given absorbing-element set type.

Input

  • SET – set type of lazy operation
  • ABS – set type of absorbing element

Output

Nothing.

Notes

This macro generates four functions (possibly two more if @neutral has been used in advance, and possibly two or four more if @declare_array_version has been used in advance).

Examples

@absorbing(MinkowskiSum, A) creates at least the following methods:

  • absorbing(::MinkowskiSum) = A
  • MinkowskiSum(X, A) = A
  • MinkowskiSum(A, X) = A
  • MinkowskiSum(A, A) = A
source
LazySets.@neutral_absorbingMacro
@neutral_absorbing(SET, NEUT, ABS)

Create two methods to avoid method ambiguities for a lazy set operation with respect to neutral-element and absorbing-element set types.

Input

  • SET – set type of lazy operation
  • NEUT – set type of neutral element
  • ABS – set type of absorbing element

Output

A quoted expression containing the function definitions.

Notes

This macro is used internally in other macros.

Examples

@neutral_absorbing(MinkowskiSum, N, A) creates the following methods as quoted expressions:

  • MinkowskiSum(N, A) = A
  • MinkowskiSum(A, N) = A
source
LazySets.@declare_binary_operationMacro
@declare_binary_operation(SET)

Create common methods for binary set operations.

Input

  • SET – set type of the lazy operation

Output

Nothing.

Notes

This macro generates seven methods. See the example below.

Examples

@declare_binary_operation(MinkowskiSum) creates the following methods:

  • iterate(::MinkowskiSum)
  • length(::MinkowskiSum)
  • getindex(::MinkowskiSum, ::Int)
  • getindex(::MinkowskiSum, ::AbstractVector{Int})
  • lastindex(::MinkowskiSum)
  • array(::MinkowskiSum)
  • is_array_constructor(::Type{MinkowskiSum})
source
LazySets.@declare_array_versionMacro
@declare_array_version(SET, SETARR)

Create methods to connect a lazy set operation with its array set type.

Input

  • SET – set type of lazy operation
  • SETARR – set type of array version

Output

Nothing.

Notes

This macro generates six methods (and possibly up to eight more if @neutral/@absorbing has been used in advance for the base and/or array set type). See the example below.

Examples

@declare_array_version(MinkowskiSum, MinkowskiSumArray) creates at least the following methods:

  • array_constructor(::Type{MinkowskiSum}) = MinkowskiSumArray
  • binary_constructor(::Type{MinkowskiSumArray}) = MinkowskiSum
  • is_array_constructor(::Type{MinkowskiSumArray}) = true
  • MinkowskiSum!(X, Y)
  • MinkowskiSum!(X, arr)
  • MinkowskiSum!(arr, X)
  • MinkowskiSum!(arr1, arr2)
source
LazySets.@array_neutralMacro
@array_neutral(FUN, NEUT, SETARR)

Create two methods to avoid method ambiguities for a lazy set operation with respect to the neutral-element set type and the array set type.

Input

  • FUN – function name
  • NEUT – set type of neutral element
  • SETARR – set type of array version

Output

A quoted expression containing the function definitions.

Examples

@array_neutral(MinkowskiSum, N, ARR) creates the following methods as quoted expressions:

  • MinkowskiSum(N, ARR) = ARR
  • MinkowskiSum(ARR, N) = ARR
source
LazySets.@array_absorbingMacro
@array_absorbing(FUN, ABS, SETARR)

Create two methods to avoid method ambiguities for a lazy set operation with respect to the absorbing-element set type and the array set type.

Input

  • FUN – function name
  • ABS – set type of absorbing element
  • SETARR – set type of array version

Output

A quoted expression containing the function definitions.

Examples

@array_absorbing(MinkowskiSum, ABS, ARR) creates the following methods as quoted expressions:

  • MinkowskiSum(ABS, ARR) = ABS
  • MinkowskiSum(ARR, ABS) = ABS
source

Types

Inspection of set interfaces

LazySets.implementing_setsFunction
implementing_sets(op::Function;
                  signature::Tuple{Vector{Type}, Int}=(Type[], 1),
                  type_args=Float64, binary::Bool=false)

Compute a dictionary containing information about availability of (unary or binary) concrete set operations.

Input

  • op – set operation (respectively its Function object)
  • signature – (optional, default: Type[]) the type signature of the function without the LazySet type(s) (see also the index option and the Examples section below)
  • index – (optional, default: 1) index of the set type in the signature in the unary case (see the binary option)
  • type_args – (optional, default: Float64) type arguments added to the LazySet(s) when searching for available methods; valid inputs are a type or nothing, and in the unary case (see the binary option) it can also be a list of types
  • binary – (optional, default: false) flag indicating whether op is a binary function (true) or a unary function (false)

Output

A dictionary with three keys each mapping to a list:

  • "available" – This list contains all set types such that there exists an implementation of op.
  • "missing" – This list contains all set types such that there does not exist an implementation of op. Note that this is the complement of the "available" list.
  • "specific" – This list contains all set types such that there exists a type-specific implementation. Note that those set types also occur in the "available" list.

In the unary case, the lists contain set types. In the binary case, the lists contain pairs of set types.

Examples

shape_matrix is only available for ellipsoids.

julia> using LazySets: implementing_sets

julia> dict = implementing_sets(shape_matrix);

julia> dict["available"]
1-element Vector{Type}:
 Ellipsoid

Every convex set type implements the function σ.

julia> dict = implementing_sets(σ; signature=Type[AbstractVector], index=2);

julia> dict["missing"]
5-element Vector{Type}:
 Complement
 DensePolynomialZonotope
 QuadraticMap
 SimpleSparsePolynomialZonotope
 SparsePolynomialZonotope

Some operations are not available for sets with rational numbers.

julia> N = Rational{Int};

julia> dict = implementing_sets(σ; signature=Type[AbstractVector{N}], index=2, type_args=N);

julia> Ball2 ∈ dict["missing"]
true

For binary functions, the dictionary contains pairs of set types. This check takes several seconds because it considers all possible set-type combinations.

julia> dict = LazySets.implementing_sets(convex_hull; binary=true);

julia> (HPolytope, HPolytope) ∈ dict["available"]
true
source

File formats

LazySets.read_genMethod
read_gen(filename::String)

Read a sequence of polygons stored in vertex representation (gen format).

Input

  • filename – path of the file containing the polygons

Output

A list of polygons in vertex representation.

Notes

The x and y coordinates of each vertex should be separated by an empty space and polygons are separated by empty lines (even the last polygon). For example:

1.01 1.01
0.99 1.01
0.99 0.99
1.01 0.99

0.908463 1.31047
0.873089 1.31047
0.873089 1.28452
0.908463 1.28452

This is parsed as

2-element Array{VPolygon{Float64, Vector{Float64}},1}:
 VPolygon{Float64, Vector{Float64}}([[1.01, 1.01], [0.99, 1.01], [0.99, 0.99], [1.01, 0.99]])
 VPolygon{Float64, Vector{Float64}}([[0.908463, 1.31047], [0.873089, 1.31047], [0.873089, 1.28452], [0.908463, 1.28452]])
source

Sampling

LazySets._sample_unit_nsphere_muller!Function
_sample_unit_nsphere_muller!(D::Vector{Vector{N}}, n::Int, p::Int;
                             [rng]::AbstractRNG=GLOBAL_RNG,
                             [seed]::Union{Int, Nothing}=nothing) where {N}

Draw samples from a uniform distribution on an $n$-dimensional unit sphere using Muller's method.

Input

  • D – output, vector of points
  • n – dimension of the sphere
  • p – number of random samples
  • rng – (optional, default: GLOBAL_RNG) random number generator
  • seed – (optional, default: nothing) seed for reseeding

Output

The modified vector D.

Algorithm

This function implements Muller's method of normalized Gaussians [1] to uniformly sample over the $n$-dimensional sphere $S^n$ (which is the bounding surface of the $n$-dimensional unit ball).

Given $n$ canonical Gaussian random variables $Z₁, Z₂, …, Z_n$, the distribution of the vectors

\[\dfrac{1}{α}\left(z₁, z₂, …, z_n\right)^T,\]

where $α := \sqrt{z₁² + z₂² + … + z_n²}$, is uniform over $S^n$.

[1] Muller, Mervin E. A note on a method for generating points uniformly on n-dimensional spheres. Communications of the ACM 2.4 (1959): 19-20.

source
LazySets.API.sampleFunction
sample(X::LazySet, [m]::Int=1;
       [rng]::AbstractRNG=GLOBAL_RNG,
       [seed]::Union{Int,Nothing}=nothing)

Compute random samples from a set.

Input

  • X – set
  • m – (optional; default: 1) number of random samples
  • rng – (optional, default: GLOBAL_RNG) random number generator
  • seed – (optional, default: nothing) seed for reseeding

Output

A vector of m elements in X if X is nonempty, and an error otherwise.

source

Extended help

sample(B::Ball2, [nsamples]::Int;
       [rng]::AbstractRNG=GLOBAL_RNG,
       [seed]::Union{Int, Nothing}=nothing)

Algorithm

Random sampling with uniform distribution in B is computed using Muller's method of normalized Gaussians. This method requires the package Distributions. See _sample_unit_nball_muller! for implementation details.

source
sample(X::LazySet{N}, num_samples::Int;
       [sampler]=_default_sampler(X),
       [rng]::AbstractRNG=GLOBAL_RNG,
       [seed]::Union{Int, Nothing}=nothing,
       [include_vertices]=false,
       [VN]=Vector{N}) where {N}

Random sampling of an arbitrary set X.

Input

  • X – set to be sampled
  • num_samples – number of random samples
  • sampler – (optional, default: _default_sampler(X)) the sampler used; falls back to CombinedSampler
  • rng – (optional, default: GLOBAL_RNG) random number generator
  • seed – (optional, default: nothing) seed for reseeding
  • include_vertices – (optional, default: false) option to include the vertices of X
  • VN – (optional, default: Vector{N}) vector type of the sampled points

Output

A vector of num_samples vectors. If num_samples is not passed, the result is just one sample (not wrapped in a vector).

Algorithm

See the documentation of the respective Sampler.

Notes

If include_vertices == true, we include all vertices computed with vertices. Alternatively if a number $k$ is passed, we plot the first $k$ vertices returned by vertices(X).

source
LazySets.AbstractSamplerType
AbstractSampler

Abstract type for defining new sampling methods.

Notes

All subtypes should implement a sample!(D, X, ::Method) method where the first argument is the output (vector of vectors), the second argument is the set to be sampled, and the third argument is the sampler instance.

source
LazySets.FaceSamplerType
FaceSampler <: AbstractSampler

Type used for sampling from the k-faces of a set.

Fields

  • dim – dimension of the faces to be sampled; a negative number is interpreted as n - dim where n is the dimension of the set

Notes

For a three-dimensional polytope, the following face dimensions exist:

  • 3-face – the polytope itself
  • 2-faces – 2-dimensional polygonal faces
  • 1-faces – 1-dimensional edges
  • 0-faces – 0-dimensional vertices

For more information see Wikipedia.

Algorithm

Currently only hyperrectangles are supported. For each point to be sampled, we randomly split the integers 1 .. n into two subgroups of size k and n-k respectively. For the i-th coordinate in the first group, we sample in the interval low(H, i) .. high(H, i). For the i-th coordinate in the second group, we randomly pick either low(H, i) or high(H, i).

source
LazySets.HalfSpaceSamplerType
HalfSpaceSampler{D} <: AbstractSampler

Type used for sampling from a half-space.

Fields

  • distribution – (optional, default: nothing) distribution from which samples are drawn

Notes

If distribution is nothing (default), the sampling algorithm uses a DefaultUniform over $[0, 1]^n$.

source
LazySets.HyperplaneSamplerType
HyperplaneSampler{D} <: AbstractSampler

Type used for sampling from a hyperplane.

Fields

  • distribution – (optional, default: nothing) distribution from which samples are drawn

Notes

If distribution is nothing (default), the sampling algorithm uses a DefaultUniform over $[0, 1]^n$.

source
LazySets.RejectionSamplerType
RejectionSampler{D} <: AbstractSampler

Type used for rejection sampling of a bounded set X.

Fields

  • distribution – (optional, default: DefaultUniform) distribution from which the sample is drawn
  • tight – (optional, default: false) set to true if the support of the distribution is known to coincide with the set X
  • maxiter – (optional, default: Inf) maximum number of iterations before giving up

Algorithm

Draw a sample $x$ from a given distribution of a box-overapproximation of the original set $X$ in all $n$ dimensions. The function rejects a drawn sample $x$ and redraws as long as the sample is not contained in the original set $X$, i.e., while $x ∉ X$.

Notes

The maxiter parameter is useful when sampling from sets that are small compared to their box approximation, e.g., flat sets, for which the probability of sampling from within the set is close to zero.

source
LazySets.RandomWalkSamplerType
RandomWalkSampler <: AbstractSampler

Type used for sampling from a convex polytope using its vertex representation. This is especially useful if rejection sampling does not work because the polytope is flat.

Fields

  • variant – (optional, default: true) choice of a variant (see below)

Notes

The sampling is not uniform - points in the center of the polytope are more likely to be sampled.

The set to be sampled from must provide its vertices via vertices_list.

Algorithm

Choose a random convex combination of the vertices of a convex polytope X.

If variant == false, we proceed as follows. Let $V = \{v_i\}_i$ denote the set of vertices of X. Then any point $p ∈ ℝ^n$ of the convex polytope $X$ is a convex combination of its vertices, i.e., $p = ∑_{i} v_i α_i$ for some (non-negative) coefficients $\{α_i\}_i$ that add up to 1. The algorithm chooses a random convex combination (the $α_i$). To produce this combination, we apply the finite-difference operator on a sorted uniform sample over $[0, 1]$; the method can be found in [1] and [2].

If variant == true, we start from a random vertex and then repeatedly walk toward a random vertex inside the polytope.

References

[1] Rubin, Donald B. The Bayesian bootstrap. The annals of statistics (1981): 130-134.

[2] StackExchange post

source
LazySets.PolynomialZonotopeSamplerType
PolynomialZonotopeSampler{D} <: AbstractSampler

Type used for sampling from polynomial zonotopes.

Fields

  • distribution – (optional, default: nothing) distribution from which samples are drawn

Notes

If distribution is nothing (default), the sampling algorithm uses a DefaultUniform over $[-1, 1]^n$.

source

Symbolics

LazySets._vecFunction
_vec(vars)

Transform a tuple of operations into one vector of operations.

Input

  • vars – tuple where each element is either variable-like (Num) or a vector of variables (Vector{Num})

Output

A vector of Operation obtained by concatenating each tuple component.

Examples

julia> using Symbolics

julia> vars = @variables x[1:2] y
2-element Vector{Any}:
  x[1:2]
 y

julia> LazySets._vec(vars)
3-element Vector{Num}:
 x[1]
 x[2]
    y
source

SymEngine

SymEngine.free_symbolsFunction
free_symbols(expr::Expr, set_type::Type{LazySet})

Return the free symbols in an expression that represents a given set type.

Input

  • expr – symbolic expression

Output

A list of symbols, in the form of SymEngine Basic objects.

Examples

julia> using LazySets: free_symbols

julia> free_symbols(:(x1 <= -0.03), HalfSpace)
1-element Vector{SymEngine.Basic}:
 x1

julia> free_symbols(:(x1 + x2 <= 2*x4 + 6), HalfSpace)
3-element Vector{SymEngine.Basic}:
 x2
 x1
 x4
source
LazySets._is_linear_combinationFunction

islinear_combination(L::Basic)

Determine whether the expression L is a linear combination of its symbols.

Input

  • L – expression

Output

true if L is a linear combination or false otherwise.

Examples

julia> using LazySets: _is_linear_combination

julia> _is_linear_combination(:(2*x1 - 4))
true

julia> _is_linear_combination(:(6.1 - 5.3*f - 0.1*g))
true

julia> _is_linear_combination(:(2*x1^2))
false

julia> _is_linear_combination(:(x1^2 - 4*x2 + x3 + 2))
false
source

Functions for numbers

LazySets.sign_cadlagFunction
sign_cadlag(x::Real)

This function works like the sign function but is $1$ for input $0$.

Input

  • x – real scalar

Output

$1$ if $x ≥ 0$, $-1$ otherwise.

Notes

This is the sign function right-continuous at zero (see càdlàg function). It can be used with vector-valued arguments via the dot operator.

Examples

julia> LazySets.sign_cadlag.([-0.6, 1.3, 0.0])
3-element Vector{Float64}:
 -1.0
  1.0
  1.0
source

Other functions

LazySets.binary_search_constraintsFunction
binary_search_constraints(d::AbstractVector{N},
                          constraints::Vector{<:HalfSpace{N}};
                          [start_index]::Int=div(length(constraints)+1, 2),
                          [choose_lower]::Bool=false) where {N}

Perform a binary search in the constraints.

Input

  • d – direction
  • constraints – constraints
  • start_index – (optional, default: div(length(constraints)+1, 2)) start index
  • choose_lower – (optional, default: false) flag for choosing the lower index (see the 'Output' section)

Output

In the default setting, the result is the smallest index k such that d ⪯ constraints[k].a, or length(constraints)+1 if no such k exists. If the choose_lower flag is set, the result is the largest index k such that constraints[k].a < d, which is equivalent to being k-1 in the normal setting.

source
LazySets.get_constrained_lowdimsetFunction
get_constrained_lowdimset(cpa::CartesianProductArray{N, S},
                          P::AbstractPolyhedron{N}) where {N, S}

Preprocessing step for the intersection between a Cartesian product of a finite number of sets and a polyhedron.

Input

  • cpa – Cartesian product of a finite number of sets
  • P – polyhedron

Output

A four-tuple of:

  1. a low-dimensional CartesianProductArray in the constrained dimensions of the original set cpa
  2. the variables in the constrained blocks,
  3. the original block structure of the low-dimensional sets,
  4. the list of the constrained blocks.
source
LazySets.get_radius!Function
get_radius!(sih::SymmetricIntervalHull{N}, i::Int) where {N}

Compute the radius of the symmetric interval hull of a set in a given dimension.

Input

  • sih – symmetric interval hull of a set
  • i – dimension in which the radius should be computed

Output

The radius of the symmetric interval hull of a set in a given dimension.

Algorithm

We ask for the extrema of the underlying set in dimension i.

source
LazySets.HalfSpaceModule.is_tighter_same_dir_2DFunction
is_tighter_same_dir_2D(c1::HalfSpace,
                       c2::HalfSpace;
                       [strict]::Bool=false)

Check if the first of two two-dimensional constraints with equivalent normal direction is tighter.

Input

  • c1 – first linear constraint
  • c2 – second linear constraint
  • strict – (optional; default: false) check for strictly tighter constraints?

Output

true iff the first constraint is tighter.

source
LazySets._leq_trigFunction
_leq_trig(u::AbstractVector{N}, v::AbstractVector{N}) where {N<:AbstractFloat}

Compare two 2D vectors by their direction.

Input

  • u – first 2D direction
  • v – second 2D direction

Output

true iff $\arg(u) [2π] ≤ \arg(v) [2π]$.

Notes

The argument is measured in counter-clockwise fashion, with the 0 being the direction (1, 0).

Algorithm

The implementation uses the arctangent function with sign, atan, which for two arguments implements the atan2 function.

source
LazySets.same_block_structureFunction
same_block_structure(x::AbstractVector{S1}, y::AbstractVector{S2}
                    ) where {S1<:LazySet, S2<:LazySet}

Check whether two vectors of sets have the same block structure, i.e., the $i$-th entry in the vectors have the same dimension.

Input

  • x – first vector
  • y – second vector

Output

true iff the vectors have the same block structure.

source
LazySets.HyperplaneModule._σ_hyperplane_halfspaceFunction
    _σ_hyperplane_halfspace(d::AbstractVector, a, b;
                            [error_unbounded]::Bool=true,
                            [halfspace]::Bool=false)

Return a support vector of a hyperplane $a⋅x = b$ in direction d.

Input

  • d – direction
  • a – normal direction
  • b – constraint
  • error_unbounded – (optional, default: true) true if an error should be thrown whenever the set is unbounded in the given direction
  • halfspace – (optional, default: false) true if the support vector should be computed for a half-space

Output

A pair (v, f) where v is a vector and f is a Boolean flag.

The flag f is false in one of the following cases:

  1. The direction has norm zero.
  2. The direction is (a multiple of) the hyperplane's normal direction.
  3. The direction is (a multiple of) the opposite of the hyperplane's normal

direction and halfspace is false. In all these cases, v is any point on the hyperplane.

Otherwise, the flag f is true, the set is unbounded in the given direction, and v is any vector.

If error_unbounded is true and the set is unbounded in the given direction, this function throws an error instead of returning.

Notes

For correctness, consider the weak duality of LPs: If the primal is unbounded, then the dual is infeasible. Since there is only a single constraint, the feasible set of the dual problem is $a ⋅ y == d$, $y ≥ 0$ (with objective function $b ⋅ y$). It is easy to see that this problem is infeasible whenever $a$ is not parallel to $d$.

source