-
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
Remove Interval <: Real ? #237
Comments
As discussed earlier, I would strongly support that. (So far I have not been able to resolve the constructor issues in #181; I think for now it is a dead end.) |
I am currently looking into that issue and complex numbers appear to be problematic. Even if the requirement to have So I think we will have to keep |
I'm not exactly sure how |
A
While I agree with this analysis (and prefer the former interpretation), it lefts out the following practical concern: all |
I disagree with your premise: The subtyping question is not about mathematical purity but about very practical concerns. The implementations in Base all assume that they are handling objects representing specific numbers and that operations on their real components behave like operations on real numbers. However, real The problem isn't that |
I think I get your point (and mainly agree with it). However I feel like it may be kind of tangential to the question of keeping or not |
I think it would be helpful because it would a) prevent silent failures when people try to use set-like intervals as drop-ins for numbers and b) open up the way to actually implementing a number-like interval which could be used like that. The current subtyping is an anti-feature: It suggests compatibility where there actually isn't any and introduces catastrophic bugs like JuliaIntervals/IntervalRootFinding.jl#86 |
That is where I get confused by your reasonning. All basic functions are redefined in this package for intervals (otherwise Julia would not know how to handle the new type, even if it is a subtype of Therefore if a method silently fails it is because it has been defined to do so in this package and having |
I am coming too late to the party, though I've spent some fair amount of time thinking about this. In my opinion, the discussion here reflects the discussion of the Interval community itself: is an Interval a set of numbers or a number? I think the usual opinion (with many disadvantages!) is to think it as an unknown number which lies inside a given set; there are other approaches that take it as the set of those possibilities. Both options have advantages and disadvantages. In my specific case, I do need that My proposal here is then pragmatical: let's provide another (new!) struct which is not a subtype of |
I have to admit I'm a little frustrated with this topic because I know we have discussed all of this before (eg. in #168 and #165): I completely understand that it seems practical to use I will not draw this fruitless discussion out further. If you want, close this bug report and move on. I guess, if you redefine |
I have to say that I have come round to @gwater's arguments here. I suggest we make a branch where we remove As regards the knock-on effects of this, there is already a type called Also, @Kolaru has a very interesting PR for defining these different "flavours", if I remember correctly. |
Sorry to hear that and to have appeared stubborn (well I may even actually be stubborn, as the next sentence may indicate x_x). I precisely think that the discussion here is different to #165 and #168, but won't draw this further either.
My main concern here is that Also I realised that if we ever want to support complex number in polar form
You probably refer to this comment in @gwater PR. It is not directly applicable to a situation with one flavour being subtype of A possible workaround is to have something like abstract type IntervalMode end
struct Strict <: IntervalMode end
struct Silent <: IntervalMode end
struct ConcreteInterval{T, M <: IntervalMode}
lo::T
hi::T
end
struct PseudoNumberInterval{T, M} <: Real
interval::ConcreteInterval{T, M}
end
struct SetInterval{T}
interval::ConcreteInterval{T, Strict}
end
AnyInterval{T, M} = Union{PseudoNumberInterval{T, M}, SetInterval{T}} and to define most functions for
There should be no performance penalty as long as Finally, note that different flavour will need to be able to interact, as for example you search the roots of a |
Since most problems seem to come from functions returning booleans, ( |
I admit I don't have much bandwidth to contribute here, but it would be great if the end result of the WIP PR is that I could use |
Thanks for your comment @ajkeller34. I guess the problem in your case is the limitation that I think the discussion here made clear that we need another type that mimics all the functionality of |
That is likely a problem, yes; also, the type parameter In Unitful, after some long discussion, it was decided that I see echoes of those discussions here, in that there is a tension between choosing a subtype that is practical for coding in the near term, and choosing an accurate subtype. Even if you have an interval type that is to be treated as a number, I am not sure strictly speaking that the interval is a real number. Some of the discussion surrounding this comment may be interesting. |
So your point is actually to relax While I agree with the essence of the comment, I'd like to listen what is the (design) reason for |
I am not sure I could pin it down to one particular design reason, but here are a few arguments in addition to the comment I linked above. One argument specific to Unitful would be that adding two real numbers is well-defined, whereas |
That would indeed be good. The current idea is to have the type allowed as interval to be determined by a trait (see #185). The rational for this is that is the nature of interval arithmetic: we can't promise correct results for just any number type (also an With a trait system, we will be able to allow any type as bound, as long as the user takes the responsability to use type with good rounding capabilities (documenting what that means exactly will be kind of hard though, but the baseline idea is they should be wrapper for some kind of |
@ajkeller34 After thoughts: while julia> using IntervalArithmetic
julia> using Unitful
julia> a = (100..110)u"g"
[100, 110] g
julia> b = (1.25..3.1)u"kg"
[1.25, 3.10001] kg
julia> a + b
[1.34999, 3.21001] kg
julia> b / 2.2u"m^2"
[0.568181, 1.4091] kg m^-2 |
That's true, and certainly helpful in many cases. (Measurements.jl also works in this way, but not the other way around, if I remember right.) However, if a package defines a struct like the following, I don't see an easy solution:
In such a case I guess the package author would have to change |
There are some issues with using IntervalArithmetic: IntervalArithmetic, interval
using Unitful: Unitful, m
a = interval(0, 0)
b = interval(0, 1)
@assert a <= b
@assert a*m <= b*m # assertion failure here Without having given it too much thought, the source of the problem is the assumption made at https://github.com/PainterQubits/Unitful.jl/blob/47d131be92eefae1b49cd02b0a9f9a55b74be97f/src/quantities.jl#L324 <=(x::AbstractQuantity, y::AbstractQuantity) = <(x,y) || x==y Although this problem wouldn't be prevented/fixed by removing the julia> a <= b
true
julia> a < b
false
julia> a == b
false |
Perhaps this is not the place to collect violations of the interface informally suggested by |
I really like this idea of actually collecting the implicit interface EDIT: Opened a discussion over on Julia Discourse |
In the 1.0-dev branch, we made several changes to improve reliability, at the cost of convenience. In this regard, the removal of I have made a local branch to experiment with removing That being said, we talked about TaylorSeries.jl. In particular, it defines abstract type AbstractSeries{T <: Number} <: Number end What would be the cost of having abstract type AbstractSeries{T} <: Number end instead? So the |
Good point! I must admit that I haven't tried it, so I'll give it a try. Perhaps, as we do it here, we should define a union type to restrict a little bit the parameter type of |
I think that we still need to have |
xref #585 |
Since ForwardDiff now no longer requires types to be
<: Real
(JuliaDiff/ForwardDiff.jl#369, although not yet in a released version), maybe it is time to makeInterval
s no longer be subtypes ofReal
.cc @gwater
The text was updated successfully, but these errors were encountered: