I've been studying interval arithmetic for the past few weeks and it's a really interesting field because while there is a ton of super interesting research published over the past decades, it has never really gotten the recognition that it deserves, IMO.
One reason for this is that standard interval arithmetic has really poor handling of division by intervals containing zero. If you compute 1 / [-1, 2] in regular interval arithmetic, you get either [-∞, +∞], or you have to say that the operation is undefined. Both solutions are virtually useless. The real answer of course is [-∞, -1] U [0.5, +∞]: i.e. a union of two disjoint intervals.
This is useful because you can confidently exclude a non empty set of the real numbers ([-1, 0.5]) from the set of possible values that you can get by dividing 1 by a number between -1 and 2.
But this definition of interval division yields a value that is not an interval. This is a problem if you want to define a closed arithmetic system, where you can build and evaluate arbitrary expression over interval values.
(This behavior extends to any non continuous function like tan() for example, which is implemented in my project - not without difficulties!)
Well the obvious solution is to define your arithmetic over disjoint unions of intervals. This is the subject of a 2017 paper called "Interval Unions" by by Schichl, H., Domes, F., Montanher, T. and Kofler, K..
This open-source project I made implements interval union arithmetic in TypeScript in the form of a simple interactive calculator, so you can try it out for yourself! The underlying TypeScript library is dependency free and implements interval union arithmetic over IEEE 754 double precision floats (JS native number type) with outward rounding. This guarantees accuracy of interval results in the presence of rounding issue inherent to floating point.
The last point in your intro description can't be stressed enough: this allows for safe handling of rounding errors in floating point operations.
Though you are inherently losing precision: there are values in the output interval which don't have a corresponding input that causes this output.
This is great. You might be interested in Matt Keeter's work on Implicit surfaces, and using interval math for its optimization:
You could add a feature where it will compute the global optimum of any function of a small number of variables. Branch and bound with interval arithmetic works well for a small number of variables.
Disjoint unions of intervals seems like a nice thing to have
You might be interested in this graphing calculator I made using interval arithmetic:
https://memalign.github.io/m/formulagraph/index.html
Some detail on how this works, including links to the relevant interval math code:
Very nice, thanks for sharing! Maybe show which upper or lower values are included in the intervals? A notation I am familiar with uses outward facing brackets if the value is not included in the interval. That always applies to infinity.
Applied to the cases here:
]-∞, -1] U [0.5, +∞[
The excluded interval in between becomes ]-1, 0.5[ then.
That’s how min (and analogously max) works, right? min(A, B) = [lo(A,B), lo (hi(A), hi(B))]
I just read up on interval arithmetic. I understand its desirable properties. Where in practice have you applied it? What’s a real world application for interval arithmetic?
Excellent!! I love interval arithmetic and also wrote a TS implementation for a graphing calculator project. Agree that it's very underrated, and I wish that directed rounding was exposed in more languages.
Neat.
Author here. Outward rounding to combat precision issues is what interval arithmetic is most known for (try 0.1+0.2 with "full precision mode" enabled), but that's really a shame in my opinion. Outward rounding is cool, but the "inclusion property", as it's known in research papers, works at every scale! This is what enables things like:
which is lovely, I think. Adding the union layer to it enables even cooler things, like the true inverse of the square function. Did you know it's not sqrt? Try 'sqinv(64)'.I made interval calculator actually mostly as a way to test my implementation of interval union arithmetic [0], which I needed for another project: a backwards updating spreadsheet [1][2].
[0] https://github.com/victorpoughon/not-so-float
[1] https://victorpoughon.github.io/bidicalc/
[2] https://news.ycombinator.com/item?id=46234734