-
Notifications
You must be signed in to change notification settings - Fork 5
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
Bug Fix: Inaccurate Tails of Incomplete Gamma #481
Conversation
064989b
to
87ef448
Compare
87ef448
to
8c8dbaa
Compare
8c8dbaa
to
d8409e0
Compare
} else { | ||
dof += 1; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any way you can incorporate this function into the test to automatically dump out the values for use in the comparisons inside the test_chi_squared_matches_gsl
unit tests? Might make any future modifications/iterations easier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with that is that we'd then need to pull GSL in as a third party library and their license (GNU public) is too restrictive for albatross. I suppose it's possible they'd allow use of the library as a test/comparison not as part of the core algorithms ... but that seems like a pretty gray area.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh never mind then.. we can stick it here https://github.com/swift-nav/shared-scratch in the future if we ever need to tweak it in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a note to that comment so we remember why we couldn't just add that output function there? Or just copy and paste into https://github.com/swift-nav/shared-scratch and add a link from orion-engine there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, sorry already merged it. but I'll follow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
follow up PR for this is fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// practice those bounds were not tight enough, particularly on the upper | ||
// bound, so we've modified this function to be more conservative | ||
return std::make_pair(std::max(0., std::min(z, a) - 12 * sqrt(a)), | ||
std::min(z, a + 13 * sqrt(a + 1))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were these bounds experimentally determined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I basically just copied the format from the master bounds, but simplified it instead of changing the multipliers (12/13 now) based on the value of a
I just set them higher than any of the previous if statements. I didn't exactly look for the lowest bound possible (so it's possible there's some wasted CPU here?) but I did increase them each until all the new tests I added passed, so they shouldn't be too crazy.
This PR fixes a bug in which the bounds to the incomplete gamma function quadrature were not sufficiently large to properly evaluate the tails. As a result evaluations of the chi squared cdf for very large values would (for specific degrees of freedom) not asymptotically approach 1.
To evaluate the discrepancy I used the GSL implementation of the incomplete gamma function to provide an alternative
chi_squared_cdf
method. Then compared the values to the one implemented in albatross. Here is the error (y-axis) as a function of the expected value (from GSL). Notice both x and y axes are log scale:The differences were not too large, mostly only ever reaching
0.001
. BUT, this can have serious consequences! Consider outlier detection, we often use the chi squared cdf as a threshold for marking an inlier. Usually that threshold is really close to 1, something like1 - 1e-6
, which can be interpreted as "throw out anything which looks like a one in a million event. Notice in the plot above that the largest errors are actually as you approach 1. What this means is that when we've given a measurement which is really bad, the chi squared cdf may only ever get as large as1 - 1e-4
, so even for insanely large residuals we may never throw out an outlier!To fix this I was able to increase the integration bounds used in the quadrature versions of the incomplete gamma:
There's still a strange blip near 1. In those cases the chi squared percentile we compute is typically larger than GSL (by at most 3e-7). So in those cases we should continue to throw out bad values, even for inlier thresholds around
0.99999999