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

Bug Fix: Inaccurate Tails of Incomplete Gamma #481

Merged
merged 4 commits into from
Apr 29, 2024

Conversation

akleeman
Copy link
Collaborator

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:

Screenshot from 2024-04-23 14-09-42

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 like 1 - 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 as 1 - 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:

Screenshot from 2024-04-23 14-10-38

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

@akleeman akleeman force-pushed the akleeman/incomplete_gamma_tails branch from 064989b to 87ef448 Compare April 23, 2024 21:56
@akleeman akleeman requested a review from peddie April 23, 2024 22:05
@akleeman akleeman force-pushed the akleeman/incomplete_gamma_tails branch from 87ef448 to 8c8dbaa Compare April 23, 2024 23:24
@akleeman akleeman force-pushed the akleeman/incomplete_gamma_tails branch from 8c8dbaa to d8409e0 Compare April 23, 2024 23:34
@akleeman akleeman requested a review from lkloh April 29, 2024 15:45
} else {
dof += 1;
}
}
Copy link
Contributor

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

Copy link
Collaborator Author

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.

Copy link
Contributor

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

Copy link
Contributor

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

Copy link
Collaborator Author

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.

Copy link
Contributor

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

Copy link
Collaborator Author

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)));
Copy link
Contributor

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?

Copy link
Collaborator Author

@akleeman akleeman Apr 29, 2024

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.

@akleeman akleeman merged commit 6725dc5 into master Apr 29, 2024
9 checks passed
@akleeman akleeman deleted the akleeman/incomplete_gamma_tails branch April 29, 2024 18:51
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

Successfully merging this pull request may close these issues.

2 participants