-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing domains as an interface #141
Conversation
I think these changes are almost completely backwards compatible with the 0.6 version of DomainSets, because functionality has mostly been added. However, the internal change is quite substantial, and I'm pretty sure that I've changed the default behaviour of |
Also, a note on The only solution is to create a new function, which I've called |
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #141 +/- ##
==========================================
- Coverage 85.70% 80.90% -4.81%
==========================================
Files 34 35 +1
Lines 2659 2697 +38
==========================================
- Hits 2279 2182 -97
- Misses 380 515 +135
☔ View full report in Codecov by Sentry. |
Probably the behaviour that makes most logical sense is then wherever is calling |
In the current design I'd say that Yes, |
Okay to merge this? |
unionbox1(d1, d2) = unionbox2(d1, d2) | ||
unionbox2(d1, d2) = fullspace(d1) | ||
unionbox1(d1::EmptySpace, d2) = d2 | ||
unionbox1(d1::FullSpace, d2) = d1 | ||
unionbox2(d1, d2::EmptySpace) = d1 | ||
unionbox2(d1, d2::FullSpace) = d2 | ||
|
||
unionbox(d1::D, d2::D) where {D<:FixedInterval} = d1 | ||
unionbox1(d1::D, d2::D) where {D<:FixedInterval} = d1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's unionbox1
and below intersectbox1
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unionbox(d1,d2)
is a function of two arguments, which sometimes simplifies for certain d1
(independently of d2
or for some possibilities of d2
). Similarly, it may simplify for certain d2
. The call chain goes:
unionbox(d1,d2)
-> unionbox1(d1,d2)
-> unionbox2(d1,d2)
-> some_default_algorithm
The idea is that unionbox1
can dispatch safely (without ambiguity) solely on d1, and unionbox2 can dispatch on d2. I've used this pattern in many places and it works rather well. If a combination of d1
and d2
is specific enough, then one can dispatch on it using just the unionbox
function.
src/domains/interval.jl
Outdated
@@ -244,8 +248,8 @@ function similar_interval(d::HalfLine{T,C}, a::S, b::S) where {T,S,C} | |||
HalfLine{promote_type(float(T),S),C}() | |||
end | |||
|
|||
point_in_domain(d::NonnegativeRealLine) = zero(eltype(d)) | |||
point_in_domain(d::PositiveRealLine) = one(eltype(d)) | |||
point_in_domain(d::NonnegativeRealLine) = zero(deltype(d)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably this name is clearer, but this is called a "choice function" in the Axiom of Choice so we could just call this choice(d)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, it would be good if choice(s)
was defined for a Set too, for example, but it isn't. This function really is just for testing purposes, but it could have any name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just add choice(d::AbstractSet) = first(d)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iterate(d)[1]
is kind of the same...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the point_in_domain
function roughly speaking picks some point in the interior of a domain, if possible. It may be good to think about how to "sample" points from a domain more generally (like rand
), but that is a separate issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I'm renaming to choice
and adding a deprecation for point_in_domain
What was breaking in this release? |
Syntactically, normally nothing. A lot of the internals changed though, which mainly results in more functionality (as opposed to functionality changing) for types that do not inherit from the main Domain type. There were some nuances in the decision whether two domains are equal which may have changed and which prompted a new series, out of caution. I would expect 0.7 to work as is for most people who had been using 0.6.x (and I'm assuming you're asking because you didn't notice a difference). |
I think this is a candidate for becoming 0.7.
It mostly implements the idea of a domain as an interface (#14, #120) and addresses some related issues ( JuliaMath/IntervalSets.jl#115, JuliaMath/IntervalSets.jl#136). The main goal is to improve interoperability with other packages.
Among other things this PR includes a copy of the contents of a newly proposed DomainSetsCore.jl package, with the exception of the definition of
Domain{T}
which remains in IntervalSets.jl for now. See core.jl for the code and the README of DomainSetsCore for a formal definition of the "domain interface". If this works well, we can still register DomainSetsCore and move the definitions there.Most importantly this PR implements all operations of DomainSets for any type, whether it inherits from Domain or not, except for functions that have a standard name outside of DomainSets. In that case, those functions are only implemented for variables of type Domain or variables which are passed "as a domain" (using the
AsDomain(d)
) syntax. A prominent example iseltype
. An alternative function which is "owned" by DomainSets isdomaineltype
.As an example of interoperability, see here for a package extension to make domains co-exist with types of GeometryBasics.jl. No changes to either packages are required, hence it could be an extension in either of the two packages. I've illustrated here what it takes for intervals of IntervalSets.jl and Intervals.jl to interact with each other.
An example of the usefulness is that in a package like DomainIntegrals.jl one can specify the integral domain as any domain (an interval from IntervalSets.jl, or from Intervals.jl, or a rectangle from GeometryBasics.jl) and it "just works". (Up to possible bugs and missing functionality for now, of course....)