JuliaIntervals / IntervalArithmetic.jl

Library for validated numerics using interval arithmetic
https://juliaintervals.github.io/IntervalArithmetic.jl/
Other
299 stars 71 forks source link

length does not work for interval ranges #281

Open dlfivefifty opened 5 years ago

dlfivefifty commented 5 years ago
julia> 1:@interval(5) |> length
ERROR: MethodError: no method matching Integer(::IntervalArithmetic.Interval{Float64})
Closest candidates are:
  Integer(::T<:Number) where T<:Number at boot.jl:741
  Integer(::Integer) at boot.jl:765
  Integer(::Union{Float32, Float64}) at boot.jl:766
  ...
Stacktrace:
 [1] unsafe_length(::UnitRange{IntervalArithmetic.Interval{Float64}}) at ./range.jl:513
 [2] length(::UnitRange{IntervalArithmetic.Interval{Float64}}) at ./range.jl:515
 [3] |>(::UnitRange{IntervalArithmetic.Interval{Float64}}, ::typeof(length)) at ./operators.jl:813
 [4] top-level scope at none:0
dpsanders commented 5 years ago

Do interval ranges make sense? Can you just use

interval.(1:5)

?

dlfivefifty commented 5 years ago

Yes I realised that shortly after submitting this issue. It seems like a bug in ApproxFun's type promotion that it even triggered this. It was in some broadcasting code.

Though apart from the usage that triggered this, I do think it makes sense: we should have

length(@interval(-1,1):@interval(-1,1)) == @interval(0,3)
dpsanders commented 5 years ago

I don't understand what that range means.

By the way, we hardly ever use @interval any more (despite the fact that it's all over the tests). It's better to use interval(a, b) (fastest) or a..b (rounds a and b) to construct intervals now.

dpsanders commented 5 years ago

(The docs need a serious update.)

dpsanders commented 5 years ago

@interval is reserved for things like

@interval sin(0.1) + cos(0.2)

where you want to treat literals inside an expression as intervals containing those true real numbers.

dlfivefifty commented 5 years ago

Ah ok, but since I'm mixing with ApproxFun which uses IntervalSets.jl, @interval is a convenient ambiguity avoider.

dpsanders commented 5 years ago

See https://juliaintervals.github.io/IntervalArithmetic.jl/latest/construction/

dpsanders commented 5 years ago

Ah it's interesting that you are using @interval like that. Is there a better syntax that we could use instead?

lucaferranti commented 2 years ago

I don't think "range of intervals" is something we want. Closing, but happy to reopen if there's a compelling argument for that.

dlfivefifty commented 2 years ago

It's needed for interval-valued infinite arrays.... which would be a step towards rigorous ∞-dimensional linear algebra (think solving linear ODEs)

lucaferranti commented 2 years ago

I see, thank you for the clarification. Reopening.

OlivierHnt commented 11 months ago

One cannot construct a StepRange with Interval in the newest release 0.22. This release is the intended design for 1.0 - although things can change. That being said, it is possible to define LinRange:

julia> LinRange(interval(1), interval(5), 3)
3-element LinRange{Interval{Float64}, Int64}:
 [1.0, 1.0]_com_NG, [3.0, 3.0]_com_NG, [5.0, 5.0]_com_NG

with the "NG" flag, which means that spooky things may be happening (or not...).

I think solving this issue requires implementing our own AbstractRange.

To get the ball rolling, we first need to know what type of ranges we want.

@dlfivefifty you mentioned infinite dimensional operators. I work on computer-assisted proof relying on spectral methods, so due to the indexing of the basis, the type of ranges involved often have a unit step (e.g. the derivative in Fourier). Would that be sufficient for your use cases as well?

dlfivefifty commented 11 months ago

No: lots of operators use other steps. Even the simple model problem of computing Bessel functions from the recurrence, where the step is 2/z.

OlivierHnt commented 11 months ago

I see. Since we cannot assume a unit step, this is a little less trivial to implement.

For some additional context: boolean functions from Base (==, etc.) are now discontinued for intervals. This prevents even more hooking into Base inner mechanism to construct ranges:

julia> 1:interval(5)
ERROR: ArgumentError: `==` is purposely not supported for intervals. See instead `isequal_interval`
...

So one would have to define a new structure, say StepRangeInterval <: AbstractRange, presumably in the vein of StepRangeLen.