Git Product home page Git Product logo

domainsetscore.jl's Introduction

Build Status Coverage

DomainSetsCore.jl

An interface package for working with domains as continuous sets of elements.

Examples of domains may be geometric sets such as intervals and triangles, or the complex plane without the negative real line. However, domains are not limited to geometry. A domain could also be a collection of vectors or arrays, such as the set of all orthogonal 3x3 matrices.

Existing types may add the interpretation of being a domain by implementing the domain interface. They gain the ability to interact with other domains.

The domain interface

The in function

A domain is a set of elements that is possibly continuous. Continuous sets are defined mathematically, not by an exhaustive list of their elements. In practice membership of the set is defined by the implementation of in. The function call in(x, domain) evaluates to true if the domain contains an element y such that y == x.

Incompatible element types

In principle, the function in(x, domain) should not throw an exception even if the types seem mathematically nonsensical. In that case, the correct return value is false. This mimicks the behaviour of in for finite sets in Julia:

julia> in(rand(3,3), 1:3)
false

Indeed, a 3x3 matrix is not equal to any of the numbers 1, 2 or 3.

The domaineltype function

The defining mathematical condition of a continuous set might be satisfied by variables of different types. Still, the interface defines the domaineltype of a domain. It is a valid type for elements of the set.

Functions that generate elements of the domain should generate elements of that type. As a consequence, for finite sets such as an AbstractArray or AbstractSet, the domaineltype agrees with the eltype of that set. For intervals on the real line, the domaineltype might be Float64. When there is no clear candidate the domaineltype might simply be Any.

Minimal formal interface

The domain interface is formally summarised in the following table:

Required methods Brief description
in(x, d) Returns true when x is an element of the domain, false otherwise
DomainStyle(d) Returns IsDomain() if d implements this interface

Optional methods include:

Important optional methods Default definition Brief description
domaineltype(d) eltype(d) Returns a valid type for elements of the domain

Several extensions of this minimal interface are defined in the DomainSets.jl package.

Domains as mathematical sets

A domain behaves as much as possible like the mathematical set it represents, irrespective of its type. Thus, for example, two domains should be considered equal if their membership functions agree.

It is not always possible to realize this intended behaviour in practice. Indeed it may be difficult to discover automatically whether two domains are equal, especially when their types are different. Still, the principle serves as a design goal.

The Domain supertype and DomainStyle trait

This package defines the abstract type Domain{T} of continuous sets with domaineltype equal to T. No concrete domain types are defined in this package.

The package also defines the trait DomainStyle. Any type can declare to implement the domain interface by defining

DomainSetsCore.DomainStyle(d::MyDomain) = IsDomain()

Objects of type Number, AbstractArray and AbstractSet are declared to be domains in this package.

Using the domain interface in practice with DomainRef

With the exception of subtypes of Domain, the set of types implementing the domain interface is not based on a common abstract supertype. Functions that are intended to manipulate domains may simply omit the type of the domain in the function signature. However, functions defined in other packages can not be extended to work for domains, as there is no common type to dispatch on. For that reason this package defines the DomainRef reference.

In the absence of function ownership, the practice of domain references requires active intent both by users and by developers. For a user, passing DomainRef(d) to a function indicates that d is to be treated as a domain. For a developer, the implementation foo(d::DomainRef) may be used to extend the functionality of foo to domains.

The reference DomainRef(d) is not in itself a domain, it is merely a reference. The developer of foo(d::DomainRef) may use domain(d) to access the domain object. More generally, one can implement foo(d::AnyDomain) and use domain(d) in the function definition. In that case the user may invoke foo both indirectly with a domain reference and directly with a concrete subtype of Domain.

Example usage

An example of this practice is the functionality of union in the DomainSets.jl package. First, the package defines a generic function uniondomain(d1,d2) with no restrictions on the types of d1 and d2. The function returns an object that behaves as the mathematical union of the two arguments. It always interprets the arguments as domains, regardless of their types.

A user wanting to use the standard syntax for this purpose has to make this intention explicit by writing DomainRef(d1) ∪ DomainRef(d2). The outcome is equivalent to uniondomain(d1, d2), and could be different from what d1 ∪ d2 means in other contexts for the combination of types of d1 and d2. That original behaviour of , quite possibly an error in fact, is not changed.

A developer may make the syntax more accessible to users as follows. As soon as one of d1 or d2 is a Domain, or a reference to a domain, the call to union can safely be interpreted as the union of domains. Thus, a developer may write:

union(d1::Anydomain, d2) = uniondomain(domain(d1), d2)
union(d1, d2::AnyDomain) = uniondomain(d1, domain(d2))
union(d1::AnyDomain, d2::AnyDomain) = uniondomain(domain(d1),domain(d2))

These definitions are safe in the sense that there is no ambiguity and no possible clash with any existing definition of union(d1,d2) in other packages.

Package interoperability

The goal of the domain interface is to make objects from different packages interoperable with minimal interaction between packages and, thus, maximal independence in their development.

Say package A and package B both define a type that can be interpreted as a domain, respectively objectA and objectB. Package C may define the domain interface for objectA using the DomainStyle trait. Package D may similarly define the domain interface for objectB. Package E could load DomainSets and packages C and D. A user of package E can type uniondomain(objectA,objectB).

This construction requires no active collaboration between the developers of packages A, B, C, D and E. They can all be developed independently. Package C relies on package A and on DomainSetsCore. Package D relies on package B and on DomainSetsCore. Package E relies on packages C, D and DomainSets. Packages C, D and E could be developed as package extensions.

More functionality with domains

Unions and intersections of domains, as well as many other set operations, are implemented generically in the DomainSets.jl package.

Intervals inheriting from the Domain supertype are implemented in IntervalSets.jl.

domainsetscore.jl's People

Contributors

daanhb avatar

Watchers

Stefanos Carlström avatar Sheehan Olver avatar Alex Townsend  avatar Marcus Webb avatar  avatar Mikael Slevinsky avatar  avatar

domainsetscore.jl's Issues

Should there be a `Domain{T}` supertype?

cfr JuliaMath/IntervalSets.jl#170 (comment)

I'd argue the contract is different for types inheriting from Domain and types implementing the domain interface.

One difference is ownership. The DomainSets package can't provide untyped fallback definitions, even if they make sense, for functions defined elsewhere. It can define untyped fallback definitions for functions specifically defined for domains (which, currently, is typically reflected in the name of the function). In the latter case, specifying the type of an object expected to be a domain to be ::Domain can be replaced by a call to checkdomain on the argument to catch any user errors.

In general it can define fallbacks only for arguments of type DomainRef, since we own that type. By inheriting from Domain{T}, a type opts-in to such fallback behaviour, without requiring its users to sprinkle their codes with DomainRef for statements that make complete sense without.

Unless I missed some kind of mechanism, not having an optional common supertype implies DomainRef's all over the place or being restricted to functions that are used only specifically in the context of DomainSets (i.e. being less generic).

Design of the package

The package is meant to:
(i) define a Domain type that can be used as supertype of continuous sets
(ii) define an interface for domains (to make it easy for other types to behave as domains and interact with each other while being developed independently)

Any suggestions welcome!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.