-
Notifications
You must be signed in to change notification settings - Fork 11
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
Any need for second order expansions computations? #7
Comments
I don't know whether this could be incoorporated in 'robust', nevertheless I wanted to drop a reference to herbie here : https://herbie.uwplse.org/ |
@daef Interesting project as well. Not sure how relevant it is for 'robust', which actually makes use of round-off errors deliberately, but still something to keep in mind for numerical stability in general. |
@daef @bluenote10 There are Herbie bindings for Rust (https://github.com/mcarton/rust-herbie-lint), but they're based on a very outdated compiler plugin approach and have long since stopped working. I've mentioned the idea of updating them before, and one of Herbie's authors offered to help, but of course nobody (i.e. me) ever has time. I'd be interested in reviving the idea if either of you are interested. The plugin worked very well for me when I used it (four years ago now)! |
While working on robustifying rust-geo-booleanops I came across something, which I'll leave here as a note -- maybe it can be useful to others.
One of the challenges of computing boolean ops on polygons is the numerical stability of line segment intersections. To study the stability, I was running many instances of random line segment intersections like this:
(The left plot is kind of a zoomed-in version of the intersection area, iterating over the raw float "grid" via
nextafter
calls. The color map shows the summed distance to the two lines computed with an arbitrary precision library.)I computed the intersection point both with an arbitrary precision library (GMP via
rug
) to get an exact groundtruth, and with plainf64
(called fast1 and fast2 in the plot, just minor variations of the common line intersection formulas). Due to cancellation effects in perp product formulas, it is not uncommon to see rather large deviations of the fast computations from the exact solution.This raised the question if it's possible to leverage the ideas behind the robust crate to get more stable results. Instead of computing results with adaptive precision, I went for a simpler approach: work with "second order expansions" only. I.e., every value is just a struct with a major and a minor component (where the major component represents the normal result of an operation and the minor component keeps track of round-off error). The implementations of the
Add
/Sub
/Mul
/Div
traits internally use the functions of the robust crate e.g. to add two second-order expansions resulting in a temporal 4-th order expansion, which then gets simplified back to a second-order before returning. Thus, the resulting precision cannot get arbitrarily long, but compared to plain floats it allows to propagate round-off errors with decent precision.It looks like this additional precision is typically enough to get the correct result in line segment intersection. The following plot shows the deltas to the exact solution for 10000 random intersections:
In all cases the second order expansion solution was identical to using full arbitrary precision.
In terms of performance using second order expansions is obviously significantly slower than raw floats, but in my benchmarks in was still an order of magnitude faster than using GMP.
Currently it looks like I do not need this feature for rust-geo-booleanops though, so probably I won't have the time to finish it up / verify it correctness etc. I just thought I leave this here just in case someone else has a need for precision in-between normal floats and arbitrary precision -- if so, feel free to ping me ;).
In case we want to turn it into a library we could either:
two_sum
,two_product
, etc. in the public interface.SOE Implementation
The text was updated successfully, but these errors were encountered: