-
Notifications
You must be signed in to change notification settings - Fork 71
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
treat intervals more like the numbers they represent #181
Conversation
Thanks for the impetus! The behaviour of many of these functions is specified in the IEEE 1788-2015 standard document for interval arithmetic packages, so changing things around is not obvious. |
What is the change that you are proposing for |
The change I am proposing is to implement I think there is a subtle misunderstanding of the relationship between |
I agree about the IEEE standard not specifying the names of functions. But IMO, an interval represents a set, not a number, so it is quite reasonable for So we could certainly add a function |
Ok, considering
Under the status quo that line leads to lots of problems because it implies that |
You have indeed hit a tricky point. I interpret this subtyping as saying something like "intervals behave like On the other hand, if we drop this, then we lose a lot of important functionality, for example automatic differentiation with ForwardDiff.jl. There is quite some previous discussion in #2. I am certainly interested to hear your thoughts. Perhaps the best way to proceed is to advertise loudly in the docs that you cannot expect any random algorithm to just work and that lots of testing is required. |
Thank you pointing out the discussion in #2, I had not read that yet. I understand that you want Intervals to be usable in 3rd party algorithms, like ForwardDiff and I fully agree that it is great that we can combine packages in julia to get awesome synergy. But that imho requires that everyone follows the specifications laid out in Base. Otherwise unpredictable behavior is unavoidable. I find this troubling especially w.r.t.
If my input function in some way interacts badly through Maybe the solution is a second type of Interval that truly acts as a drop-in, i.e. for set operations it promotes to |
This would not really solve the problem, as it would not give the ability to check if a given third party algorithm is suitable or not for the use of abstract type Behavior end
struct SetLike <: Behavior end
struct NumberLike <: Behavior end
const DefaultBehavior = NumberLike
abstract type AbstractInterval{T} <: Real end
struct Interval{T<:Real, B<: Behavior} <: AbstractInterval{T}
lo :: T
hi :: T
end
# Two very naive constructor for the example.
Interval(a::T, b::T) where {T<:Real} = Interval{T, DefaultBehavior}(a, b)
Interval(::Type{B}, a::T, b::T) where {B <: Behavior, T <: Real} = Interval{T, B}(a, b)
function ==(a::Interval{T1, SetLike}, b::Interval{T2, SetLike}) where {T1 <: Real, T2 <: Real}
isempty(a) && isempty(b) && return true
a.lo == b.lo && a.hi == b.hi
end
function ==(a::Interval{T1, NumberLike}, b::Interval{T2, NumberLike}) where {T1 <: Real, T2 <: Real}
isthin(a) && isequal(a, b) && return true
isempty(a ∩ b) && return false
throw(UndecidableError("may represent equal numbers (or not)"))
end The current type system allows to omit the trailing type parameters, which implies that here Interval{T} == Interval{T, B} where {B <: Behavior} And so the current syntax could still be used in methods definitions where it does not matter. Ideally the user should be able to choose the default behavior (it is perhaps possible to do similar to how the path to the python interpreter is passed to PyCall). |
@Kolaru Thank you for providing that incredibly elegant solution. It really would allow most code to be shared, leaving only the handful of functions I modified to be re-implemented (plus figuring out the implications for various constructors). |
I'm trying to implement your idea @Kolaru and I'm running into errors like this
basically anytime the constructor is called like |
@gwater I think that you need to explicitly implement the general method
|
e0d84c6
to
91669e3
Compare
@gwater Could you push your changes so we can see where the problem comes from ? I tried my previous suggestion and I can't reproduce your error. I use the following definition of the struct Interval{T<:Real, B<:Behavior} <: AbstractInterval{T}
lo :: T
hi :: T
function Interval{T, B}(a::Real, b::Real) where {T<:Real, B<:Behavior}
if validity_check && !is_valid_interval(a, b)
throw(ArgumentError("Interval of form [$a, $b] not allowed. Must have a ≤ b to construct Interval(a, b)."))
end
new(a, b)
end
end |
Sorry, I cannot work out how to get the current master to work with 0.6 or 1.0 (because there are no .toml files even though 0.7 is required). Basically, julia refuses constructors like
Pre-compilation crashes with a stack overflow. |
Support for Julia 0.6 has been dropped. On Julia 1.0, just do
which will check out git master into a local directory that you can edit.
If that is an outer constructor, then (I believe you need) the new syntax:
|
Thanks for the help. So in Julia 1.0 try the following (on this branch):
and you get
The branch currently has the constructor which was suggested. |
I think before we put more time into this solution we should decide #237 though. Because if we agree that Intervals are not Numbers this pull request is obsolete. |
I think the error is related to the need of an outer constructor for |
To use current master on 1.0, in the REPL type `]` (backwards square
bracket) to enter `pkg` mode, and then
```
add IntervalArithmetic#master
```
This also works from the Jupyter notebook.
The latest version no longer supports Julia 0.6. I strongly suggest
upgrading to Julia 1.0.
…On Mon, Oct 22, 2018 at 8:43 AM Josua Grawitter ***@***.***> wrote:
Sorry, I cannot work out how to get the current master to work with 0.6 or
1.0 (because there are no .toml files even though 0.7 is required).
Basically, julia refuses constructors like
Interval{T}(a::T, b::T) = Interval{T, DefaultBehavior}(a, b)
Pre-compilation crashes with a stack overflow.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#181 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AALtTlOVGSnTjK78qdbIoD0ESImz_N5oks5uncuCgaJpZM4VTEK5>
.
--
Dr. David P. Sanders
Profesor Titular "B" / Associate Professor
Departamento de Física, Facultad de Ciencias
Universidad Nacional Autónoma de México (UNAM)
dpsanders@g <dpsanders@ciencias.unam.mx>mail.com / Twitter: @davidpsanders
<https://twitter.com/DavidPSanders>
http://sistemas.fciencias.unam.mx/~dsanders / GitHub: dpsanders
<https://github.com/dpsanders>
Cubículo / office: #414, 4o. piso del Depto. de Física
Tel.: (+52 55) 5622 4965
|
Apparently there are problems with GitHub right now.
On Mon, Oct 22, 2018 at 8:52 AM David P. Sanders <dpsanders@gmail.com>
wrote:
… To use current master on 1.0, in the REPL type `]` (backwards square
bracket) to enter `pkg` mode, and then
```
add IntervalArithmetic#master
```
This also works from the Jupyter notebook.
The latest version no longer supports Julia 0.6. I strongly suggest
upgrading to Julia 1.0.
On Mon, Oct 22, 2018 at 8:43 AM Josua Grawitter ***@***.***>
wrote:
> Sorry, I cannot work out how to get the current master to work with 0.6
> or 1.0 (because there are no .toml files even though 0.7 is required).
> Basically, julia refuses constructors like
>
> Interval{T}(a::T, b::T) = Interval{T, DefaultBehavior}(a, b)
>
> Pre-compilation crashes with a stack overflow.
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <#181 (comment)>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AALtTlOVGSnTjK78qdbIoD0ESImz_N5oks5uncuCgaJpZM4VTEK5>
> .
>
--
Dr. David P. Sanders
Profesor Titular "B" / Associate Professor
Departamento de Física, Facultad de Ciencias
Universidad Nacional Autónoma de México (UNAM)
***@***.*** ***@***.***>mail.com / Twitter: @davidpsanders
<https://twitter.com/DavidPSanders>
http://sistemas.fciencias.unam.mx/~dsanders / GitHub: dpsanders
<https://github.com/dpsanders>
Cubículo / office: #414, 4o. piso del Depto. de Física
Tel.: (+52 55) 5622 4965
--
Dr. David P. Sanders
Profesor Titular "B" / Associate Professor
Departamento de Física, Facultad de Ciencias
Universidad Nacional Autónoma de México (UNAM)
dpsanders@g <dpsanders@ciencias.unam.mx>mail.com / Twitter: @davidpsanders
<https://twitter.com/DavidPSanders>
http://sistemas.fciencias.unam.mx/~dsanders / GitHub: dpsanders
<https://github.com/dpsanders>
Cubículo / office: #414, 4o. piso del Depto. de Física
Tel.: (+52 55) 5622 4965
|
In order to get the ball rolling on #168 and #165 I'm starting this pull request. I imagine there is still a lot of discussion ahead of us but hopefully this will help us get a better idea and something concrete to interrogate.
The most significant change here is redefining
==
to be in line with its definition inBase
:(emphasis added by me)
Obviously that breaks a lot of test cases and probably some parts of
IntervalArithmetic
andIntervalRootFinding
which rely on==
comparing the boundaries of two intervals. I have renamed the old behaviorisequal()
, in line with its definition inBase
: