# Interval Hulls

In this section we illustrate the interval hull operators as well as several plotting functionalities.

## Balls and Singletons

Consider a ball in the 2-norm. By default, the coefficients of this set are 64-bit floating point numbers. Other numeric types (such as lower precision floating point, or rational) can be defined with the proper argument types in the `Ball2`

constructor.

```
using Plots, LazySets
X = Ball2(ones(2), 0.5)
```

`Ball2{Float64, Vector{Float64}}([1.0, 1.0], 0.5)`

To plot a lazy set, we use the `plot`

function. By design, lazy sets plots overapproximate with box directions only. To have a sharp definition of the borders, use the accuracy as a second argument.

`plot(X, 1e-3, aspectratio=1)`

To add plots to the same pair of axes we use `plot!`

. Let's add some points of the set which are farthest in some given directions. Single points can be plotted using the `Singleton`

type. In the third line of code we plot the center of the ball picking a custom cross marker.

```
plot!(Singleton(σ([1., 0], X)))
plot!(Singleton(σ([1., 1], X)))
plot!(Singleton(X.center), markershape=:x)
```

To see the list of available plot keyword arguments, use the `plotattr([attr])`

function, where `attr`

is the symbol `:Plot`

, `:Series`

, `:Axis`

or `:Subplot`

.

For the remainder of this section we define another ball in the 2-norm and its convex hull with `X`

.

```
Y = Ball2([-3,-.5], 0.8)
Z = CH(X, Y)
plot(X, 1e-3, aspectratio=1)
plot!(Y, 1e-3)
plot!(Z, 1e-3, alpha=0.2)
```

## Ballinf approximation

A simple overapproximation with a `BallInf`

is obtained with the `ballinf_approximation`

function, from the `Approximations`

module. It overapproximates a convex set by a tight ball in the infinity norm by evaluating the support vector in the canonical directions.

```
import LazySets.Approximations.ballinf_approximation
plot(X, 1e-3, aspectratio=1)
plot!(Y, 1e-3)
plot!(Z, 1e-3, alpha=0.2)
Bapprox = ballinf_approximation(Z)
plot!(Bapprox, alpha=0.1)
plot!(Singleton(Bapprox.center), markershape=:x)
```

`Bapprox.center, Bapprox.radius`

`([-1.15, 0.09999999999999998], 2.65)`

## Interval hull approximation

If we want to have different lengths for each dimension, instead of the `ballinf_approximation`

, we can use the approximation with a hyperrectangle through the `interval_hull`

function.

```
import LazySets.Approximations.interval_hull
plot(X, 1e-3, aspectratio=1)
plot!(Y, 1e-3)
plot!(Z, 1e-3, alpha=0.2)
Happrox = interval_hull(Z)
plot!(Happrox, alpha=0.1)
plot!(Singleton(Happrox.center), markershape=:x)
```

`Happrox.center, Happrox.radius`

`([-1.15, 0.09999999999999998], [2.65, 1.4])`

The `interval_hull`

function is an alias for the `box_approximation`

function. The nomenclature for approximation functions is `*_approximation_*`

. To see a list of all approximation functions, either search in the docs or type `names(LazySets.Approximations)`

.

## Symmetric interval hull

Contrary to the previous approximations, the symmetric interval hull is centered around the origin. It is defined in the `Approximations`

module as well.

```
import LazySets.Approximations.symmetric_interval_hull
using SparseArrays
plot(X, 1e-3, aspectratio=1)
plot!(Y, 1e-3)
plot!(Z, 1e-3, alpha=0.2)
S = symmetric_interval_hull(Z)
plot!(S, alpha=0.2)
plot!(Singleton(S.center), markershape=:x)
```

`S.center, S.radius`

`([0.0, 0.0], [3.8, 1.5])`

We can get the list of vertices using the `vertices_list`

function:

`vertices_list(S)`

```
4-element Vector{Vector{Float64}}:
[3.8, 1.5]
[-3.8, 1.5]
[3.8, -1.5]
[-3.8, -1.5]
```

For instance, compute the support vector in the south-east direction:

`σ([1., -1.], S)`

```
2-element Vector{Float64}:
3.8
-1.5
```

It is also possible to pass a sparse vector as direction, and the result is a sparse vector:

`σ(sparsevec([1., -1.]), S)`

```
2-element SparseArrays.SparseVector{Float64, Int64} with 2 stored entries:
[1] = 3.8
[2] = -1.5
```

## Norm, radius and diameter

In this part we illustrate some functions to obtain metric properties of sets, applied to the sets `X`

, `Y`

and `Z`

defined previously, in the infinity norm. These functions apply generally to any `LazySet`

. For some types, specialized methods are triggered automatically through multiple-dispatch.

The *norm* of a convex set is the norm of the enclosing ball (of the given norm) of minimal volume. For instance:

```
import LazySets.Approximations: norm, radius, diameter
norm(X), norm(Y), norm(Z)
```

`(1.5, 3.8, 3.8)`

The *radius* of a convex set. It is the radius of the enclosing ball (of the given norm) of minimal volume with the same center. In the previous example,

`radius(X), radius(Y), radius(Z)`

`(0.5, 0.8, 2.65)`

Finally, it is sometimes convenient to ask directly the diameter of the set, defined as twice the radius:

`diameter(X), diameter(Y), diameter(Z)`

`(1.0, 1.6, 5.3)`