Skip to content

Commit

Permalink
tweaks and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
daanhb committed Apr 5, 2024
1 parent 8b935b3 commit 891ea2f
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 73 deletions.
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ makedocs(;
pages=[
"Home" => "index.md",
"Examples" => "examples.md",
"Set operations" => "setoperations.md",
"Specific domains" => Any[
"Euclidean geometry" => "geometry.md",
"Function approximation" => "approximation.md",
"Complex analysis" => "complex.md",
"Numbers" => "numbers.md"
],
"Set operations" => "setoperations.md",
"Design principles" => Any[
"The domain interface" => "interface.md",
"Equality of domains" => "equality.md",
Expand Down
30 changes: 25 additions & 5 deletions docs/src/equality.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,41 @@ it may be difficult to discover automatically whether two domains are equal,
especially when their types are different. Deciding whether two domains are equal requires supporting implementation, hence the outcome is not always accurate.
Still, the principle serves as a design goal.

## The `isequaldomain` function

Equality of domains is decided by the `isequaldomain` function in general, and
simply by `==` for subtypes of the `Domain` supertype.
```julia
julia> UnitInterval() == UnitSimplex{Float64}() == 0..1
true

julia> ChebyshevInterval() == UnitBall{Float64}() == -1 .. 1
true
```
The methodology behind this example is explained in the section on
[Canonical domains](@ref).

!!! note
If two domains are equal according to `==`, then their hashes are also equal.
This allows the use of domains as keys in a `Dict`, if one is so inclined.

Equality of domains is decided by the `isequaldomain` function in general, and
simply by `==` for subtypes of the `Domain` supertype.

```@docs; canonical=false
isequaldomain
```

!!! note
If two domains are equal according to `==`, then their hashes are also equal.
This allows the use of domains as keys in a `Dict`, if one is so inclined.

## Types versus mathematical sets

In some cases the notion of a set is more interesting than the functionality
provided by the membership function. A concrete type offers a representation of
a notion. Having a type for the real numbers (see [``](@ref)) allows one to
specify the domain of a function of a real variable.

A type can also be convenient for other reasons. Although a ball with center and radius can be represented in terms of an affine map and a unit ball, not all affine maps
map the unit ball to a ball. Thus, in Julia, such a representation does not allow one to dispatch on the property of being a ball.

Yet, having more types also comes with disadvantages. Dispatching on the type of
a domain such as an `Interval` does not make a function apply to all intervals - because a scalar unit ball has a different type but mathematically is also an interval.

This tension is not resolved in the package. Still, deciding whether two domains are equal is a relevant aspect.
4 changes: 2 additions & 2 deletions docs/src/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

These are the same examples as those in the README of the package repository.

## Intervals
## Intervals from IntervalSets

DomainSets.jl uses [IntervalSets.jl](https://github.com/JuliaMath/IntervalSets.jl) for closed and open intervals. In addition, it defines a few standard intervals.

Expand Down Expand Up @@ -101,7 +101,7 @@ the 3-dimensional open unit ball
```


## Product domains
## Cartesian products

The cartesian product of domains is constructed with the `ProductDomain` or
`ProductDomain{T}` constructor. This abstract constructor returns concrete types
Expand Down
105 changes: 92 additions & 13 deletions docs/src/geometry.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@
Domains appearing in geometry are an important special case. A small number of
primitive domains are implemented.

Several of these may be open or closed.

DomainSets favours the definition of canonical types without state, which can
be implemented as singleton types without fields. It is made easy to map the
be implemented as singleton types without fields or data. It is made easy to map the
canonical domain to a more specific one, often using
an affine map. See: [Canonical domains](@ref), and in particular the functions [`mapfrom_canonical`](@ref) and [`mapto_canonical`](@ref).
an affine map. See: [Canonical domains](@ref).

## A note on Euclidean dimension

For example, each ball, with any given radius and any center,
can be obtained as the translation and scaling of a unit ball with radius one
centered at the origin.
The Euclidean dimension of a domain can be implicit in the element type, if it
is scalar or a static vector. One could have `T=Float64` or
`T = SVector{3,Float64}` for 3D domains. The dimension can also be variable, if the element type is a `Vector{T}`. In the latter case the dimension is typically
explicitly stored in a field of the type. In the former case the dimension is implicit in the type and the type itself can be stateless.

!!! note
`DomainSets` imposes no preference and enables both representations. Among other
things, this leads to having more types, sometimes with funny or unexpected names.
For example, `StaticUnitBall{T}` is a singleton type,
whose dimension is fixed by the element type `T`. The word "static" in the name of the type refers to this aspect of dimensionality being known at compile-time.
The alternative is `DynamicUnitBall{T}`. This is a domain with element type `Vector{T}`, whose dimension is explicitly stored in a field.


## Intervals
Expand All @@ -28,24 +40,91 @@ A number of intervals with fixed endpoints, known at compile-time, are added in

## Rectangles and cubes

Rectangles and cubes are implemented as a `ProductDomain` (see [Product domains](@ref)).
They can be obtained by passing closed intervals to the `ProductDomain` constructor,
or by invoking the `Rectangle` constructor.

Two special cases are the `UnitSquare` and `UnitCube` types. These types have no state.

## Balls and spheres
Some examples:
```julia
julia> ProductDomain(1.5..2.5, 3.5..6.0)
(1.5 .. 2.5) × (3.5 .. 6.0)

The type hierarchy is as follows:
julia> [0.5,0.3] UnitSquare()
true

julia> [0.5,0.3,0.1] UnitCube()
true

julia> ProductDomain(UnitInterval(), UnitInterval())
UnitSquare()

julia> Rectangle([0.0,1.0,2.0], [1.0,4.0,6.0])
(0.0 .. 1.0) × (1.0 .. 4.0) × (2.0 .. 6.0)
```
abstract Ball
|-> abstract UnitBall: radius is 1
|-> StaticUnitBall: dimension is part of type
|-> DynamicUnitBall: dimension is specified by int field
|-> GenericBall: stores center and radius. Here, the dimension can be
obtained from the center, so there is only one type.

##### Relevant functions

```@docs; canonical=false
Rectangle
UnitSquare
UnitCube
```

## Balls and spheres

The unit ball in a space is the volume consisting of all points `x` for which
`norm(x) < 1` or `norm(x) ≤ 1`, depending on whether the ball is open or closed.
The sphere is the boundary of the volume, i.e., the set of points for which
`norm(x) = 1`.

The canonical ball is a `UnitBall`, which can either have a dimension determined
by the element type `T` or, in case of `Vector` elements, a dimension that is
specified explicitly.

The constructor of the abstract type `Ball` returns a suitable concrete type depending on the arguments.

Types and syntax for spheres are analogous to those of balls.
```julia
julia> UnitBall()
UnitBall()

julia> Ball(3.0)
Ball(3.0, [0.0, 0.0, 0.0])

julia> Ball(3.0, [0.4, 2.0, 5.0])
Ball(3.0, [0.4, 2.0, 5.0])

julia> Ball{SVector{3,Float64}}(3, [0, 1, 2])
Ball(3.0, [0.0, 1.0, 2.0])

julia> eltype(ans)
SVector{3, Float64}
```

##### Relevant functions

```@docs; canonical=false
Ball()
Sphere()
UnitBall()
UnitSphere()
```

The unit disk and unit circle are special cases in 2D.
```@docs; canonical=false
UnitDisk
UnitCircle
```


## Simplices

The type hierarchy is similar to that of balls. The abstract supertype
`UnitSimplex` has a constructor which returns a suitable concrete subtype
depending on the arguments.

```@docs; canonical=false
UnitSimplex()
```
2 changes: 1 addition & 1 deletion docs/src/setoperations.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ TupleProductDomain
Rectangle
```

## Union of sets
## Set union

The mathematical union of two sets is guaranteed by `uniondomain`, while a lazy
union is returned by `UnionDomain`.
Expand Down
Loading

2 comments on commit 891ea2f

@daanhb
Copy link
Member Author

@daanhb daanhb commented on 891ea2f Apr 5, 2024

Choose a reason for hiding this comment

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

@JuliaRegistrator register

Release notes:

much improved documentation
simplify and parameterdomain work recursively and catch more simplifications/parameterizations
bug fix in canonical domain of points

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/104311

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.7.11 -m "<description of version>" 891ea2f1403c56f17479a802f045611549c8f9fd
git push origin v0.7.11

Please sign in to comment.