Skip to content
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

Semantics of non-standard empty intervals #12

Closed
dmcclean opened this issue Mar 25, 2014 · 11 comments
Closed

Semantics of non-standard empty intervals #12

dmcclean opened this issue Mar 25, 2014 · 11 comments

Comments

@dmcclean
Copy link
Collaborator

Prelude> :m Numeric.Interval
Numeric.Interval> let xs = I 2.0 (-3.0)
Numeric.Interval> width xs
-5.0
Numeric.Interval> midpoint xs
-0.5

Contradicting the bog standard definitions, though there may be alternate definitions with which I am unfamiliar.

I'm not sure if you would prefer to document the existing behavior or add a null case, so I haven't prepared a pull request.

It's also possible that I'm not seeing a reason why the existing behavior is beneficial for some clients, I don't tend to use interval/interval arithmetic much in my applications.

@ekmett
Copy link
Owner

ekmett commented Mar 25, 2014

The problem comes down to how do you do this without analyzing the values involved.

An example where the case based approach is really bad is when you go to such a case analysis based approach is, say, using Interval with accelerate.

There is a definition of interval arithmetic that allows for this symmetric form. They are called "Kaucher intervals" or directed intervals.

I'm open to a more invasive approach, perhaps by splitting Numeric.Interval into two modules, on with the directed/Kaucher semantics and the other with the textbook interval definition, but it isn't a pure win either way.

Regardless, the current behavior should be much better documented though. midpoint and width for example only give sensible results for non-null intervals.

Several other definitions should be updated to reflect this in their description as well.

@dmcclean
Copy link
Collaborator Author

I was thinking about that too, I don't think it can even be done for width with such a general context.

The deeper analysis at issue being (a) requiring an Ord a instance, and (b) requiring that the 0 value from Num a actually obeys the law that, for all x in a, x - x = 0.

width :: Num a => Interval a -> a
width (I a b) = b - a

to

width :: (Ord a, Num a) => Interval a -> a
width i | null i = 0
width (I a b) = b - a

(I'm not familiar with accelerate, but Hoogle points me to a package for getting pipelined things to run on GPUs, is that what you mean? If so I'm glad I asked, because that wasn't even on my radar.)

It might be that my needs are better served by splitting. One option would be to look at the data-interval package (which normalizes empty intervals at construction time, and doesn't export the raw constructor); I originally looked past it because it requires a Num context everywhere and allows open/closed everywhere.

Another option would be to resurrect a prototype I did last year that handles closed/open, infinite, semi-infinite, and cyclic intervals but requires a non-standard class that plays the role of Ord, and a whole bunch of type families; I put it aside because it was too complicated, though it would be nice for a full-blown database language.

@dmcclean
Copy link
Collaborator Author

Here's some interesting work on this topic. http://www.jucs.org/jucs_1_7/on_directed_interval_arithmetic/Markov_S.pdf

(I think) it offers a way to describe "ordinary" interval arithmetic on top of directed interval arithmetic, which might be a useful path to, as you said, "splitting Numeric.Interval into two modules, on with the directed/Kaucher semantics and the other with the textbook interval definition". As far as I can tell, all the intervals arithmetic operations align with these definitions. I can't tell what, if anything, this document says about how the various containment operations are defined for directed intervals. I am also having trouble digging up an answer elsewhere on the internet, except for some seemingly unresolved arguments on the mailing list for a working group working on an IEEE standard for interval arithmetic. I can't follow what's happening in the AERN-Real-Interval package well enough to tell either.

@ekmett
Copy link
Owner

ekmett commented Mar 26, 2014

I'd be okay with repurposing Numeric.Interval to be a proper Interval type, and make Numeric.Interval.Kaucher have the existing directed semantics.

/cc'ing @bergey and @byorgey from diagrams, as they also use Interval at last check, so they can know what is going on.

@byorgey
Copy link

byorgey commented Mar 26, 2014

Thanks for cc'ing us. We use Interval to properly keep track of precision when doing various approximations, mostly having to do with Bezier curves. If we ever do like we've been threatening for a while and abstract over the numeric types underlying diagrams, I imagine the existing directed semantics which doesn't require ordering checks etc. would be important for us. So as long as that stays around in some form we'd be happy. Having to update some of our code to change imports etc. would be no problem.

@ekmett
Copy link
Owner

ekmett commented Mar 26, 2014

I've started work on 0.4, which does this split.

@ekmett
Copy link
Owner

ekmett commented Mar 26, 2014

Feel free to check my logic, as it was a marathon refactoring session this morning.

@ekmett
Copy link
Owner

ekmett commented Mar 26, 2014

Also, we may want a Numeric.Interval.NonEmpty, which isn't directed, but is never empty with appropriate instances as a middle ground.

@ekmett
Copy link
Owner

ekmett commented Mar 28, 2014

Done.

@ekmett ekmett closed this as completed Mar 28, 2014
@dmcclean
Copy link
Collaborator Author

Awesome. Thanks for all the help!

@ekmett
Copy link
Owner

ekmett commented Mar 29, 2014

and vice versa. =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants