Repository navigation
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was assisted by Claude. The reference code in R was written by human.
Summary
Zhang and Stephens (2009) method requires that first quartile is bigger than the smallest value.
psis_smooth_tail()passes the excessesexp(lw_tail) - exp(cutoff)togpdfit(). When a quarter of them are 0, the first quartilex_1st_qtis 0, and the gridthetadivides by it and becomes-Inf. The product-theta * xis then NaN for the zero excesses, sokandsigmaare NaN. The test!std::isinf(k)lets NaN through, the smoothed tail is NaN, and(llr_weights.array() < 0.0).select(llr_weights, 0.0)maps NaN to 0. Each tail draw gets the weightexp(0) = 1. Thek > 0.7warning does not fire for NaN.Zero excesses occur in these cases:
exp()underflows to 0 for them;-Inf, whichsingle.hppsets when the log density throws astd::domain_error.Example (100 draws, tail length 20): 70 log ratios from -20 to -26.9, 15 at -5, and 15 from -3.5 to 0. The cutoff and 5 tail values are -5.
developreturns 1 for all 20 tail draws; the correct unsmoothed weights areexp(lr), for exampleexp(-5) = 0.0067for the 5 tied draws.When the tied minimum is positive (a quarter of the tail ties above the cutoff),
thetais finite, andgpdfit()fits a sample that is far from a generalized Pareto distribution.posterior::gpdfit()returnsNAfor both cases, with the same check on the first quartile.Intended Effect
gpdfit()returns NaN forsigmaandkwhen the first quartile ofxis not larger than its smallest value.psis_smooth_tail()smooths only for a finitek. Otherwise it returns the tail unchanged.psis_weights()logs a warning whenkis not finite and returns the weights without smoothing, as it already does for a constant tail.This behavior matches the behavior of corresponding function in posterior R package.
How to Verify
./runTests.py src/test/unit/services/pathfinder. The three new tests inpsis_test.cppare:gpdfit_tied_first_quartile: 4 of 20 values at the minimum give a finite fit; 5 of 20 at a minimum of 0, and 5 of 20 at a minimum of 0.001, give NaN.psis_weights_tied_cutoff: the example above. The weights must equalexp(lr), and the warning must be logged.psis_weights_underflow_in_tail: 85 log ratios from -1000 to -1084 and 15 from -3.5 to 0, so 5 tail values and the cutoff underflow. The same checks.With the
developpsis.hppand the new tests, the 3 new tests fail (42 expectations) and the 5 existing tests pass. With this PR all 8 pass.eight_schools_testandnormal_glm_testalso pass.Tested with
develop849cec8daand Stan Mathe4745c87ff, g++ 14.3.0, Linux x86_64.Side Effects
The results do not change when the first quartile of the excesses is larger than their minimum. The existing PSIS tests and the Pathfinder service tests pass without changes. A tail with a quarter of its values tied at a positive minimum is no longer smoothed.
Documentation
gpdfit()andpsis_smooth_tail()describe the new return values.Copyright and Licensing
Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company):
Aalto University
By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses: