-
-
Notifications
You must be signed in to change notification settings - Fork 191
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
Quick fix for notable problems with neg_binomial_2 and neg_binomial_2_log #1622
Quick fix for notable problems with neg_binomial_2 and neg_binomial_2_log #1622
Conversation
…gs/RELEASE_500/final)
…gs/RELEASE_500/final)
@syclik Those are IMHO the only fixes worth pushing to the release. It's getting late here, so will likely respond to any inquiries tomorrow morning. |
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.
This all looks good. I added a couple questions on one of the tests. I agree looking in R it seems like the threshold to turn this into a Poisson should be much higher. Maybe we can work out a better condition in a later pull.
I think it makes sense to add simple autodiff tests since it's easy and makes it clear that the values and gradients are consistent with each other. Something super rough like:
#include <test/unit/math/test_ad.hpp>
#include <limits>
TEST(mathMixScalFun, neg_binomial_2_log_lpmf_derivatives) {
auto f1 = [](const auto& eta, const auto& phi) { return stan::math::neg_binomial_2_log_lpmf(0, eta, phi); };
auto f2 = [](const auto& eta, const auto& phi) { return stan::math::neg_binomial_2_log_lpmf(6, eta, phi); };
stan::test::expect_ad(f1, -1.5, 4.1);
stan::test::expect_ad(f1, 2.0, 1.1);
stan::test::expect_ad(f2, -1.5, 4.1);
stan::test::expect_ad(f2, 2.0, 1.1);
}
and then the same for neg_binomial_2_lpmf.
} | ||
} | ||
|
||
TEST(ProbDistributionsNegBinomial2, derivativesComplexStep) { |
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.
What do the complex step tests cover that the others don't?
These fancy tests are for neg_binomial_2_log_lpmf. Should they cover neg_binomial_2_lpmf as well?
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.
What do the complex step tests cover that the others don't?
They are able to test gradients numerically to (much) higher precision than what is possible with finite diffs. They are also able to cover large phi
values where the precomputed
test is not used, since Mathematica (at least the free cloud version) gives up on computing exact answers for large phi
.
These fancy tests are for neg_binomial_2_log_lpmf. Should they cover neg_binomial_2_lpmf as well?
Well, they should :-) And I do have them written in #1497 . The thing is I am aiming for really a minimal PR and the tests fail (unless weakened noticeably), because there are all sorts of minor issues with the numerics that require more time to be handled. I don't think there is any particularly defensible line on what tests to include (and hence what issues to address). I went with "avoid obvious bugs (positive log prob., overwriting logp
)".
You may disagree on the specific choice or with the whole concept of the quick fix, obviously. I am myself not 100% happy with leaving so many holes, and maybe waiting for a full fix is a better option in some sense.
Thanks @bbbales2 for looking into it.
Yes, I added those, but between the distribution tests and the precomputed tests from Mathematica, I am not sure this adds much value.
I think I already did that in #1497 (you may witness me slowly starting to grasp this over time in the comments :-) ). The answer seems to be: "Delegating to Poisson is finicky. If you improve the numerics, you can avoid the Poisson branch completely and circumvent of all sorts of issues (ensuring continuity around the cutoff, making sure |
…xp1~20180509124008.99 (branches/release_50)
The build fails on "Windows headers & unit" with
And nothing more... is this an issue with Jenkins or is there somewhere to investigate what that means? |
Also, I had to move the cutoff for |
Just to be clear (since I agree it's kindof annoying for me to ask for these), it gives me confidence that all the basic mechanics are right. Things like double, double vs var, double vs double, var vs fvar, double work. Also if I spot check the prim numerics once in R or something, then I can kinda have faith that things are generalizing, and that gives me confidence that your high precision tests are testing the right thing (and aren't just high precision testing something else).
I restarted the tests. We can merge when the tests pass. |
I agree this is important, I just thought this is what the "Distribution tests" (the tests under
Thanks |
Good point lol.
Nah nah, you're good. |
} | ||
} | ||
|
||
TEST(mathMixScalFun, neg_binomial_2_log_lpmf_derivatives) { |
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, I shoulda caught this. This should be in mix, but given how long the tests have taken merge this anyway and we can just move this to mix with the next pull.
Jenkins Console Log Machine informationProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010CPU: G++: Clang: |
I think this can be merged, right? I'm pretty sure @syclik was fine with it if it had tests and approval. |
Summary
Minimal changes to avoid some (but not all) pathological behaviour of the
neg_binomial_2
variants.neg_binomial_2
no longer overrides thelogp
accumulator whenphi > 1e5
. This cutoff forphi
is too low, but I ended up not increasing it as larger cutoff breaks the current finite diffs tests (purely because the test is wrong, the returned derivatives are good, finite diffs are waaaaay off).neg_binomial_2_log
now delegates to Poisson forphi > 1e5
to avoid returning positive log. prob.In both cases, I am aware that the computation is not stable in some cases, but those fixes should improve the situation for current release.
Tests
neg_binomial_2_lpmf
where a vector of values, some below and some above thephi
cutoff are passed.neg_binomial_2_log_lpmf
comparing against precomputed values from Mathematica (cannot be computed for values ofphi
above the1e10
cutoff).neg_binomial_2_lpmf
andneg_binomial_2_log_lpmf
across a broad range of values.neg_binomial_2_lpmf
against a complex-step derivative across a range of values.Side Effects
When
propto=TRUE
and somephi
values trigger the Poisson code path, the normalizing constant is not properly handled (forneg_binomial_2_lpmf
, this was the case before this PR, but now this will also affectneg_binomial_2_log_lpmf
)Checklist
Math issue neg_binomial_2_log_lpmf is not stable for large phi #1495 and partially The way neg_binomial_2_lpmf delegates to Poisson is broken #1496
Copyright holder: Institute of Microbiology of the Czech Academy of Sciences
The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
- Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
the basic tests are passing
./runTests.py test/unit
)make test-headers
)make doxygen
)make cpplint
)the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested