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

Fixing negative binomial phi cutoff #1497

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
d95e377
Failing test for cutoff when delegate neg_binomial_2 to poisson
martinmodrak Dec 9, 2019
25b8ebe
Failing test for vectors needing cutoff
martinmodrak Dec 9, 2019
e47d5d7
Phi cutoff no longer overrides logp accumulator
martinmodrak Dec 9, 2019
6f76adf
Failing test for propto conservation around the cutoff
martinmodrak Dec 9, 2019
211dd5b
Merge commit 'fd244866e1ff9fd3988516b39f54c8870d46fba1' into HEAD
yashikno Dec 9, 2019
b43aa0d
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Dec 9, 2019
8bcd8b4
Using binomial_coefficient_log, better Poisson defer, further tests
martinmodrak Dec 10, 2019
c96d9d8
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Dec 10, 2019
7b992e9
Fixed formatting issues
martinmodrak Dec 10, 2019
64e034f
Improved tests and their reporting
martinmodrak Dec 11, 2019
09ec4f1
Merge commit '45231d114908d5a7d236fed9dffa2501ee8e368b' into HEAD
yashikno Dec 11, 2019
a6eccc8
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Dec 11, 2019
50653af
Updated precomputed test values
martinmodrak Dec 11, 2019
02865a9
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Dec 11, 2019
abc6858
Changing order of operations, passing precomputed test
martinmodrak Dec 11, 2019
2dcbb82
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Dec 11, 2019
b6bf80c
Removed unnecessary debug info
martinmodrak Dec 11, 2019
85059fd
Use precomputed values
martinmodrak Dec 11, 2019
788c894
Test for continuity of gradients at cutoff
martinmodrak Dec 11, 2019
8ec6a37
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Dec 11, 2019
eb7f7fc
Updated Mathematica code+reference
martinmodrak Dec 11, 2019
d54bedd
Removing old code
martinmodrak Dec 11, 2019
c306f5a
Test with complex_step WIP
martinmodrak Dec 18, 2019
5976cff
Merge branch 'develop' into bugfix/1496-poisson-phi-cutoff
rok-cesnovar Dec 19, 2019
2745243
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Dec 19, 2019
06f926a
Changing finite diffs to complex step
martinmodrak Dec 19, 2019
653cc46
Merge remote-tracking branch 'origin/bugfix/1496-poisson-phi-cutoff' …
martinmodrak Dec 19, 2019
69083c7
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Dec 19, 2019
6f5a9d2
Moved test values to separate namespace
martinmodrak Dec 19, 2019
9dd904f
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Dec 19, 2019
dae4a78
Updated comments
martinmodrak Dec 19, 2019
fe8a133
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Dec 19, 2019
6cd8b9d
Fixed #1531 for neg_binomial_2_lpmf
martinmodrak Jan 2, 2020
7607ff4
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Jan 2, 2020
fdab10c
Moved tests touched by the flattening
martinmodrak Jan 2, 2020
8c8283d
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 2, 2020
d19a2a4
Fixed missing length reference
martinmodrak Jan 2, 2020
3acfeaf
Merge remote-tracking branch 'origin/bugfix/1496-poisson-phi-cutoff' …
martinmodrak Jan 2, 2020
3493b14
Using for range-based for loops
martinmodrak Jan 2, 2020
699ca25
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jan 2, 2020
f5bee19
Addressing review
martinmodrak Jan 3, 2020
22cdefe
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Jan 3, 2020
b5f40b1
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jan 3, 2020
ccbecdf
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Jan 3, 2020
00f612a
Test large n in derivativesComplexStep, correctly name tests
martinmodrak Jan 3, 2020
5fcc1d4
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 3, 2020
0c4cb47
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Jan 6, 2020
faaf580
Addressing review, boost upgrade
martinmodrak Jan 6, 2020
90add5d
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 6, 2020
f186b88
Fixed include typo
martinmodrak Jan 6, 2020
4c9da27
Merge remote-tracking branch 'origin/bugfix/1496-poisson-phi-cutoff' …
martinmodrak Jan 6, 2020
d051928
Removed use of unsigned int
martinmodrak Jan 6, 2020
ab8827c
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 6, 2020
f15e7e0
Tightened test acuraccy
martinmodrak Jan 6, 2020
cbd0234
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 6, 2020
315d9b1
Precomputed (failing) test for binomial_coefficient_log
martinmodrak Jan 7, 2020
c070cc6
More tests, avoiding Poisson
martinmodrak Jan 7, 2020
9156ab5
Merge commit 'e33558fefaa40ebf5f5153d585b968491b494f98' into HEAD
yashikno Jan 7, 2020
7c4a819
[Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~e…
stan-buildbot Jan 7, 2020
70fedb4
Dummy and failing test for lgamma_stirling_diff
martinmodrak Jan 8, 2020
9d936af
Merge commit '821d3b15263f6e4a6d27c7fe77f0f80d3eafb8ed' into HEAD
yashikno Jan 8, 2020
08e4203
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jan 8, 2020
45d9f99
Some progress towards better binomial_coefficient_log (messy)
martinmodrak Jan 9, 2020
1f441e0
Merge commit '77fe4a0e493ed3b26bb08a33d0c18b7cf40602cb' into HEAD
yashikno Jan 9, 2020
fb8718b
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 9, 2020
a0d0ba5
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Jan 10, 2020
8e461ad
Some more tweaks to stirling_diff
martinmodrak Jan 10, 2020
1d38cf3
More (still failing) work on lgamma_stirling_diff
martinmodrak Jan 10, 2020
3f12906
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 10, 2020
a85623a
Failing test for lbeta (#1611)
martinmodrak Jan 13, 2020
d2f955a
More strict criteria in expect_near_rel
martinmodrak Jan 13, 2020
9e708af
Fixing lbeta and binomial_coefficient_log (#1611, #1592)
martinmodrak Jan 13, 2020
a791f8f
Fixing derivative w.r.t. phi for large difference between mu and phi
martinmodrak Jan 13, 2020
d5caa44
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Jan 13, 2020
70430fb
Fixes after merge
martinmodrak Jan 13, 2020
36f24d7
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 13, 2020
4c48fc6
More fixes after merge
martinmodrak Jan 13, 2020
9601a2b
Merge remote-tracking branch 'origin/bugfix/1496-poisson-phi-cutoff' …
martinmodrak Jan 13, 2020
584d505
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 13, 2020
a85d449
LOG_TWO_PI
martinmodrak Jan 13, 2020
6e50269
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 13, 2020
446f042
Minor optimization in lgamma_stirling_dff
martinmodrak Jan 13, 2020
52dce3c
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 13, 2020
e505f53
Fixing lint, cleanup
martinmodrak Jan 14, 2020
ec5e5ed
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 14, 2020
a36ac43
Merge branch 'bugfix/1592-binomial_coefficient_log' into bugfix/1496-…
martinmodrak Jan 14, 2020
10fdef9
Fixing incomplete merge
martinmodrak Jan 14, 2020
a408d8e
Merge branch 'bugfix/1592-binomial_coefficient_log' into bugfix/1496-…
martinmodrak Jan 14, 2020
e420333
Improved code style
martinmodrak Jan 14, 2020
fbe958d
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 14, 2020
54d821d
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Mar 13, 2020
e560179
Fixed merge
martinmodrak Mar 13, 2020
815f0a9
Fixes #1496
martinmodrak Mar 13, 2020
360478c
Reducing the scope of neg_binomial_2_log_lpmf tests
martinmodrak Mar 13, 2020
1e121d3
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Mar 13, 2020
ce9e525
Fixed duplicated from merge
martinmodrak Mar 15, 2020
56a4d22
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Mar 15, 2020
fb55067
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Mar 15, 2020
63bafd7
A bit more cleanup
martinmodrak Mar 15, 2020
6cfff52
Removed unused headers
martinmodrak Mar 15, 2020
4ef18c9
Merge remote-tracking branch 'stan-dev/develop' into bugfix/1496-pois…
martinmodrak Mar 29, 2020
ce0b062
Test against dphi for n = 1, lifted lbeta test restrictions
martinmodrak Mar 29, 2020
4b2f032
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Mar 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stan/math/opencl/kernel_generator/load.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class load_
* Creates a deep copy of this expression.
* @return copy of \c *this
*/
inline load_<T&> deep_copy() const & { return load_<T&>(a_); }
inline load_<T&> deep_copy() const& { return load_<T&>(a_); }
inline load_<T> deep_copy() && { return load_<T>(std::forward<T>(a_)); }

/**
Expand Down
50 changes: 20 additions & 30 deletions stan/math/prim/prob/neg_binomial_2_lpmf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/binomial_coefficient_log.hpp>
#include <stan/math/prim/fun/digamma.hpp>
#include <stan/math/prim/fun/lgamma.hpp>
#include <stan/math/prim/fun/log.hpp>
#include <stan/math/prim/fun/max_size.hpp>
#include <stan/math/prim/fun/multiply_log.hpp>
#include <stan/math/prim/fun/size.hpp>
#include <stan/math/prim/fun/size_zero.hpp>
#include <stan/math/prim/fun/value_of.hpp>
#include <stan/math/prim/prob/poisson_lpmf.hpp>
#include <cmath>

namespace stan {
Expand Down Expand Up @@ -47,7 +46,7 @@ return_type_t<T_location, T_precision> neg_binomial_2_lpmf(
size_t size_phi = stan::math::size(phi);
size_t size_mu_phi = max_size(mu, phi);
size_t size_n_phi = max_size(n, phi);
size_t max_size_seq_view = max_size(n, mu, phi);
size_t size_all = max_size(n, mu, phi);

VectorBuilder<true, T_partials_return, T_location> mu_val(size_mu);
for (size_t i = 0; i < size_mu; ++i) {
Expand Down Expand Up @@ -76,39 +75,30 @@ return_type_t<T_location, T_precision> neg_binomial_2_lpmf(
n_plus_phi[i] = n_vec[i] + phi_val[i];
}

for (size_t i = 0; i < max_size_seq_view; i++) {
// if phi is large we probably overflow, defer to Poisson:
if (phi_val[i] > 1e5) {
// TODO(martinmodrak) This is wrong (doesn't pass propto information),
// and inaccurate for n = 0, but shouldn't break most models.
// Also the 1e5 cutoff is too small.
// Will be addressed better in PR #1497
logp += poisson_lpmf(n_vec[i], mu_val[i]);
} else {
if (include_summand<propto>::value) {
logp -= lgamma(n_vec[i] + 1.0);
}
if (include_summand<propto, T_precision>::value) {
logp += multiply_log(phi_val[i], phi_val[i]) - lgamma(phi_val[i]);
}
if (include_summand<propto, T_location>::value) {
logp += multiply_log(n_vec[i], mu_val[i]);
}
if (include_summand<propto, T_precision>::value) {
logp += lgamma(n_plus_phi[i]);
}
logp -= n_plus_phi[i] * log_mu_plus_phi[i];
for (size_t i = 0; i < size_all; i++) {
if (include_summand<propto, T_precision>::value) {
logp += binomial_coefficient_log(n_plus_phi[i] - 1, n_vec[i]);
}
if (include_summand<propto, T_location>::value) {
logp += multiply_log(n_vec[i], mu_val[i]);
}
logp += -phi_val[i] * (log1p(mu_val[i] / phi_val[i]))
- n_vec[i] * log_mu_plus_phi[i];

if (!is_constant_all<T_location>::value) {
ops_partials.edge1_.partials_[i]
+= n_vec[i] / mu_val[i] - n_plus_phi[i] / mu_plus_phi[i];
+= n_vec[i] / mu_val[i] - (n_vec[i] + phi_val[i]) / (mu_plus_phi[i]);
}
if (!is_constant_all<T_precision>::value) {
ops_partials.edge2_.partials_[i] += 1.0 - n_plus_phi[i] / mu_plus_phi[i]
+ log_phi[i] - log_mu_plus_phi[i]
- digamma(phi_val[i])
+ digamma(n_plus_phi[i]);
T_partials_return log_term;
if (mu_val[i] < phi_val[i]) {
log_term = log1p(-mu_val[i] / (mu_plus_phi[i]));
} else {
log_term = log_phi[i] - log_mu_plus_phi[i];
}
ops_partials.edge2_.partials_[i]
+= (mu_val[i] - n_vec[i]) / (mu_plus_phi[i]) + log_term
- (digamma(phi_val[i]) - digamma(n_plus_phi[i]));
}
}
return ops_partials.build(logp);
Expand Down
5 changes: 4 additions & 1 deletion test/unit/math/prim/prob/neg_binomial_2_log_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,10 @@ TEST(ProbNegBinomial2, log_matches_lpmf) {
TEST(ProbDistributionsNegBinomial2Log, neg_binomial_2_log_grid_test) {
std::vector<double> mu_log_to_test
= {-101, -27, -3, -1, -0.132, 0, 4, 10, 87};
std::vector<double> phi_to_test = {2e-5, 0.36, 1, 2.3e5, 1.8e10, 6e16};
// TODO(martinmodrak) Reducing the span of the test, should be fixed
// along with #1495
// std::vector<double> phi_to_test = {2e-5, 0.36, 1, 10, 2.3e5, 1.8e10, 6e16};
martinmodrak marked this conversation as resolved.
Show resolved Hide resolved
std::vector<double> phi_to_test = {0.36, 1, 10};
std::vector<int> n_to_test = {0, 1, 10, 39, 101, 3048, 150054};

// TODO(martinmdorak) Only weak tolerance for this quick fix
Expand Down
50 changes: 32 additions & 18 deletions test/unit/math/prim/prob/neg_binomial_2_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <test/unit/math/prim/prob/vector_rng_test_helper.hpp>
#include <test/unit/math/prim/prob/NegativeBinomial2LogTestRig.hpp>
#include <test/unit/math/prim/prob/VectorIntRNGTestRig.hpp>
#include <test/unit/math/expect_near_rel.hpp>
#include <gtest/gtest.h>
#include <boost/random/mersenne_twister.hpp>
#include <boost/math/distributions.hpp>
Expand Down Expand Up @@ -238,27 +239,40 @@ TEST(ProbDistributionsNegBinomial2, chiSquareGoodnessFitTest4) {
}

TEST(ProbDistributionsNegBinomial2, extreme_values) {
int N = 100;
double mu = 8;
double phi = 1e12;
for (int n = 0; n < 10; ++n) {
phi *= 10;
double logp = stan::math::neg_binomial_2_log<false>(N, mu, phi);
EXPECT_LT(logp, 0);
std::vector<int> n_to_test = {0, 1, 5, 100, 12985, 1968422};
std::vector<double> mu_to_test = {1e-5, 0.1, 8, 713, 28311, 19850054};
for (double mu : mu_to_test) {
for (int n : n_to_test) {
// Test across a range of phi
for (double phi = 1e12; phi < 1e22; phi *= 10) {
double logp = stan::math::neg_binomial_2_log<false>(n, mu, phi);
EXPECT_LT(logp, 0) << "n = " << n << ", mu = " << mu
<< ", phi = " << phi;
}
}
}
}

TEST(ProbDistributionsNegBinomial2, vectorAroundCutoff) {
int y = 10;
double mu = 9.36;
std::vector<double> phi;
phi.push_back(1);
phi.push_back(1e15);
double vector_value = stan::math::neg_binomial_2_lpmf(y, mu, phi);
double scalar_value = stan::math::neg_binomial_2_lpmf(y, mu, phi[0])
+ stan::math::neg_binomial_2_lpmf(y, mu, phi[1]);

EXPECT_FLOAT_EQ(vector_value, scalar_value);
TEST(ProbDistributionsNegBinomial2, zeroOne) {
using stan::test::expect_near_rel;

std::vector<double> mu_to_test = {2.345e-5, 0.2, 13, 150, 1621, 18432, 1e10};
double phi_start = 1e-8;
double phi_max = 1e22;
for (double mu : mu_to_test) {
for (double phi = phi_start; phi < phi_max; phi *= stan::math::pi()) {
std::stringstream msg;
msg << ", mu = " << mu << ", phi = " << phi;

double expected_value_0 = phi * (-log1p(mu / phi));
double value_0 = stan::math::neg_binomial_2_lpmf(0, mu, phi);
expect_near_rel("n = 0 " + msg.str(), value_0, expected_value_0);

double expected_value_1 = (phi + 1) * (-log1p(mu / phi)) + log(mu);
double value_1 = stan::math::neg_binomial_2_lpmf(1, mu, phi);
expect_near_rel("n = 1 " + msg.str(), value_1, expected_value_1);
}
}
}

TEST(ProbDistributionsNegativeBinomial2Log, distributionCheck) {
Expand Down
5 changes: 0 additions & 5 deletions test/unit/math/rev/fun/lbeta_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@ TEST(MathFunctions, lbeta_identities_gradient) {
// Successors: beta(a,b) = beta(a + 1, b) + beta(a, b + 1)
for (double x : to_test) {
for (double y : to_test) {
// TODO(martinmodrak) this restriction on testing should be lifted once
// the log_sum_exp bug (#1679) is resolved
if (x > 1e10 || y > 1e10) {
continue;
}
auto rh = [](const var& a, const var& b) {
return stan::math::log_sum_exp(lbeta(a + 1, b), lbeta(a, b + 1));
};
Expand Down
Loading