Skip to content

Commit f2bebaf

Browse files
committed
Merge remote-tracking branch 'lingium/feature/issue-3113-beta-neg-binomial-lccdf' into HEAD
2 parents 73c4066 + dcb7bee commit f2bebaf

10 files changed

Lines changed: 64 additions & 50 deletions

makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ doxygen:
8787
clean:
8888
@echo ' removing generated test files'
8989
@$(RM) $(wildcard test/prob/generate_tests$(EXE))
90+
@$(RM) $(EXPRESSION_TESTS) $(call findfiles,test/expressions,*_test.cpp)
9091
@$(RM) $(call findfiles,test/prob,*_generated_v_test.cpp)
9192
@$(RM) $(call findfiles,test/prob,*_generated_vv_test.cpp)
9293
@$(RM) $(call findfiles,test/prob,*_generated_fd_test.cpp)

runTests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ def checkToolchainPathWindows():
383383
universal_newlines=True,
384384
)
385385
out, err = p1.communicate()
386-
if re.search(" |\(|\)", out):
386+
if re.search(r" |\(|\)", out):
387387
stopErr(
388388
"The RTools toolchain is installed in a path with spaces or bracket. Please reinstall to a valid path.",
389389
-1,

stan/math/prim/fun/grad_F32.hpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ namespace math {
4949
* @param[in] max_steps number of steps to take
5050
*/
5151
template <bool grad_a1 = true, bool grad_a2 = true, bool grad_a3 = true,
52-
bool grad_b1 = true, bool grad_b2 = true, bool grad_z = true,
53-
typename T1, typename T2, typename T3, typename T4, typename T5,
54-
typename T6, typename T7, typename T8 = double>
52+
bool grad_b1 = true, bool grad_b2 = true, bool grad_z = true,
53+
typename T1, typename T2, typename T3, typename T4, typename T5,
54+
typename T6, typename T7, typename T8 = double>
5555
void grad_F32(T1* g, const T2& a1, const T3& a2, const T4& a3, const T5& b1,
5656
const T6& b2, const T7& z, const T8& precision = 1e-6,
5757
int max_steps = 1e5) {
@@ -87,47 +87,53 @@ void grad_F32(T1* g, const T2& a1, const T3& a2, const T4& a3, const T5& b1,
8787
log_t_new += log(fabs(p)) + log_z;
8888
log_t_new_sign = p >= 0.0 ? log_t_new_sign : -log_t_new_sign;
8989
if constexpr (grad_a1) {
90-
term[0] = log_g_old_sign[0] * log_t_old_sign * exp(log_g_old[0] - log_t_old)
91-
+ inv(a1 + k);
90+
term[0]
91+
= log_g_old_sign[0] * log_t_old_sign * exp(log_g_old[0] - log_t_old)
92+
+ inv(a1 + k);
9293
log_g_old[0] = log_t_new + log(fabs(term[0]));
9394
log_g_old_sign[0] = term[0] >= 0.0 ? log_t_new_sign : -log_t_new_sign;
9495
g[0] += log_g_old_sign[0] * exp(log_g_old[0]);
9596
}
9697

9798
if constexpr (grad_a2) {
98-
term[1] = log_g_old_sign[1] * log_t_old_sign * exp(log_g_old[1] - log_t_old)
99+
term[1]
100+
= log_g_old_sign[1] * log_t_old_sign * exp(log_g_old[1] - log_t_old)
99101
+ inv(a2 + k);
100102
log_g_old[1] = log_t_new + log(fabs(term[1]));
101103
log_g_old_sign[1] = term[1] >= 0.0 ? log_t_new_sign : -log_t_new_sign;
102104
g[1] += log_g_old_sign[1] * exp(log_g_old[1]);
103105
}
104106

105107
if constexpr (grad_a3) {
106-
term[2] = log_g_old_sign[2] * log_t_old_sign * exp(log_g_old[2] - log_t_old)
108+
term[2]
109+
= log_g_old_sign[2] * log_t_old_sign * exp(log_g_old[2] - log_t_old)
107110
+ inv(a3 + k);
108111
log_g_old[2] = log_t_new + log(fabs(term[2]));
109112
log_g_old_sign[2] = term[2] >= 0.0 ? log_t_new_sign : -log_t_new_sign;
110113
g[2] += log_g_old_sign[2] * exp(log_g_old[2]);
111114
}
112115

113116
if constexpr (grad_b1) {
114-
term[3] = log_g_old_sign[3] * log_t_old_sign * exp(log_g_old[3] - log_t_old)
117+
term[3]
118+
= log_g_old_sign[3] * log_t_old_sign * exp(log_g_old[3] - log_t_old)
115119
- inv(b1 + k);
116120
log_g_old[3] = log_t_new + log(fabs(term[3]));
117121
log_g_old_sign[3] = term[3] >= 0.0 ? log_t_new_sign : -log_t_new_sign;
118122
g[3] += log_g_old_sign[3] * exp(log_g_old[3]);
119123
}
120124

121125
if constexpr (grad_b2) {
122-
term[4] = log_g_old_sign[4] * log_t_old_sign * exp(log_g_old[4] - log_t_old)
126+
term[4]
127+
= log_g_old_sign[4] * log_t_old_sign * exp(log_g_old[4] - log_t_old)
123128
- inv(b2 + k);
124129
log_g_old[4] = log_t_new + log(fabs(term[4]));
125130
log_g_old_sign[4] = term[4] >= 0.0 ? log_t_new_sign : -log_t_new_sign;
126131
g[4] += log_g_old_sign[4] * exp(log_g_old[4]);
127132
}
128133

129134
if constexpr (grad_z) {
130-
term[5] = log_g_old_sign[5] * log_t_old_sign * exp(log_g_old[5] - log_t_old)
135+
term[5]
136+
= log_g_old_sign[5] * log_t_old_sign * exp(log_g_old[5] - log_t_old)
131137
+ inv(z);
132138
log_g_old[5] = log_t_new + log(fabs(term[5]));
133139
log_g_old_sign[5] = term[5] >= 0.0 ? log_t_new_sign : -log_t_new_sign;

stan/math/prim/fun/grad_pFq.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,11 @@ template <bool calc_a = true, bool calc_b = true, bool calc_z = true,
8989
typename T_Rtn = return_type_t<Ta, Tb, Tz>,
9090
typename Ta_Rtn = promote_scalar_t<T_Rtn, plain_type_t<Ta>>,
9191
typename Tb_Rtn = promote_scalar_t<T_Rtn, plain_type_t<Tb>>>
92-
inline std::tuple<Ta_Rtn, Tb_Rtn, T_Rtn> grad_pFq(const TpFq& pfq_val, const Ta& a,
93-
const Tb& b, const Tz& z,
94-
double precision = 1e-14,
95-
int max_steps = 1e6) {
92+
inline std::tuple<Ta_Rtn, Tb_Rtn, T_Rtn> grad_pFq(const TpFq& pfq_val,
93+
const Ta& a, const Tb& b,
94+
const Tz& z,
95+
double precision = 1e-14,
96+
int max_steps = 1e6) {
9697
using std::max;
9798
using Ta_Array = Eigen::Array<return_type_t<Ta>, -1, 1>;
9899
using Tb_Array = Eigen::Array<return_type_t<Tb>, -1, 1>;

stan/math/prim/fun/hypergeometric_3F2.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ namespace internal {
1919
template <typename Ta, typename Tb, typename Tz,
2020
require_all_vector_t<Ta, Tb>* = nullptr,
2121
require_stan_scalar_t<Tz>* = nullptr>
22-
inline return_type_t<Ta, Tb, Tz> hypergeometric_3F2_infsum(const Ta& a, const Tb& b, const Tz& z,
23-
double precision = 1e-6,
24-
int max_steps = 1e5) {
22+
inline return_type_t<Ta, Tb, Tz> hypergeometric_3F2_infsum(
23+
const Ta& a, const Tb& b, const Tz& z, double precision = 1e-6,
24+
int max_steps = 1e5) {
2525
using T_return = return_type_t<Ta, Tb, Tz>;
2626
Eigen::Array<scalar_type_t<Ta>, 3, 1> a_array = as_array_or_scalar(a);
27-
Eigen::Array<scalar_type_t<Tb>, 3, 1> b_array = append_row(as_array_or_scalar(b), 1.0);
27+
Eigen::Array<scalar_type_t<Tb>, 3, 1> b_array
28+
= append_row(as_array_or_scalar(b), 1.0);
2829
check_3F2_converges("hypergeometric_3F2", a_array[0], a_array[1], a_array[2],
2930
b_array[0], b_array[1], z);
3031

@@ -141,7 +142,8 @@ inline auto hypergeometric_3F2(const Ta& a, const Tb& b, const Tz& z) {
141142
template <typename Ta, typename Tb, typename Tz,
142143
require_all_stan_scalar_t<Ta, Tb, Tz>* = nullptr>
143144
inline auto hypergeometric_3F2(const std::initializer_list<Ta>& a,
144-
const std::initializer_list<Tb>& b, const Tz& z) {
145+
const std::initializer_list<Tb>& b,
146+
const Tz& z) {
145147
return hypergeometric_3F2(std::vector<Ta>(a), std::vector<Tb>(b), z);
146148
}
147149

stan/math/prim/prob/beta_neg_binomial_lccdf.hpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ inline return_type_t<T_r, T_alpha, T_beta> beta_neg_binomial_lccdf(
6161
check_positive_finite(function, "Prior success parameter", alpha_ref);
6262
check_positive_finite(function, "Prior failure parameter", beta_ref);
6363

64-
6564
scalar_seq_view<T_n> n_vec(n);
6665
scalar_seq_view<T_r_ref> r_vec(r_ref);
6766
scalar_seq_view<T_alpha_ref> alpha_vec(alpha_ref);
@@ -94,24 +93,23 @@ inline return_type_t<T_r, T_alpha, T_beta> beta_neg_binomial_lccdf(
9493
auto r_plus_n = r_dbl + n_dbl;
9594
auto a_plus_r = alpha_dbl + r_dbl;
9695
using a_t = return_type_t<decltype(b_plus_n), decltype(r_plus_n)>;
97-
using b_t = return_type_t<decltype(n_dbl), decltype(a_plus_r), decltype(b_plus_n)>;
98-
auto F
99-
= hypergeometric_3F2(
100-
std::initializer_list<a_t>{1.0, b_plus_n + 1.0, r_plus_n + 1.0},
101-
std::initializer_list<b_t>{n_dbl + 2.0, a_plus_r + b_plus_n + 1.0}, 1.0);
96+
using b_t = return_type_t<decltype(n_dbl), decltype(a_plus_r),
97+
decltype(b_plus_n)>;
98+
auto F = hypergeometric_3F2(
99+
std::initializer_list<a_t>{1.0, b_plus_n + 1.0, r_plus_n + 1.0},
100+
std::initializer_list<b_t>{n_dbl + 2.0, a_plus_r + b_plus_n + 1.0},
101+
1.0);
102102
auto C = lgamma(r_plus_n + 1.0) + lbeta(a_plus_r, b_plus_n + 1.0)
103-
- lgamma(r_dbl) - lbeta(alpha_dbl, beta_dbl)
104-
- lgamma(n_dbl + 2);
103+
- lgamma(r_dbl) - lbeta(alpha_dbl, beta_dbl) - lgamma(n_dbl + 2);
105104
log_ccdf += C + stan::math::log(F);
106105

107106
if constexpr (!is_constant_all<T_r, T_alpha, T_beta>::value) {
108-
auto digamma_n_r_alpha_beta
109-
= digamma(a_plus_r + b_plus_n + 1.0);
107+
auto digamma_n_r_alpha_beta = digamma(a_plus_r + b_plus_n + 1.0);
110108
T_partials_return dF[6];
111-
grad_F32<false, !is_constant<T_beta>::value,
112-
!is_constant_all<T_r>::value, false, true, false>(dF, 1.0,
113-
b_plus_n + 1.0, r_plus_n + 1.0, n_dbl + 2.0,
114-
a_plus_r + b_plus_n + 1.0, 1.0, precision, max_steps);
109+
grad_F32<false, !is_constant<T_beta>::value, !is_constant_all<T_r>::value,
110+
false, true, false>(dF, 1.0, b_plus_n + 1.0, r_plus_n + 1.0,
111+
n_dbl + 2.0, a_plus_r + b_plus_n + 1.0, 1.0,
112+
precision, max_steps);
115113

116114
if constexpr (!is_constant<T_r>::value || !is_constant<T_alpha>::value) {
117115
auto digamma_r_alpha = digamma(a_plus_r);

stan/math/prim/prob/wiener5_lpdf.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -679,12 +679,12 @@ inline auto wiener_lpdf(const T_y& y, const T_a& a, const T_t0& t0,
679679
if (!include_summand<propto, T_y, T_a, T_t0, T_w, T_v, T_sv>::value) {
680680
return ret_t(0.0);
681681
}
682-
using T_y_ref = ref_type_if_t<!is_constant<T_y>::value, T_y>;
683-
using T_a_ref = ref_type_if_t<!is_constant<T_a>::value, T_a>;
684-
using T_t0_ref = ref_type_if_t<!is_constant<T_t0>::value, T_t0>;
685-
using T_w_ref = ref_type_if_t<!is_constant<T_w>::value, T_w>;
686-
using T_v_ref = ref_type_if_t<!is_constant<T_v>::value, T_v>;
687-
using T_sv_ref = ref_type_if_t<!is_constant<T_sv>::value, T_sv>;
682+
using T_y_ref = ref_type_t<T_y>;
683+
using T_a_ref = ref_type_t<T_a>;
684+
using T_t0_ref = ref_type_t<T_t0>;
685+
using T_w_ref = ref_type_t<T_w>;
686+
using T_v_ref = ref_type_t<T_v>;
687+
using T_sv_ref = ref_type_t<T_sv>;
688688

689689
static constexpr const char* function_name = "wiener5_lpdf";
690690

stan/math/prim/prob/wiener_full_lpdf.hpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,14 @@ inline auto wiener_lpdf(const T_y& y, const T_a& a, const T_t0& t0,
327327
return ret_t(0);
328328
}
329329

330-
using T_y_ref = ref_type_if_t<!is_constant<T_y>::value, T_y>;
331-
using T_a_ref = ref_type_if_t<!is_constant<T_a>::value, T_a>;
332-
using T_v_ref = ref_type_if_t<!is_constant<T_v>::value, T_v>;
333-
using T_w_ref = ref_type_if_t<!is_constant<T_w>::value, T_w>;
334-
using T_t0_ref = ref_type_if_t<!is_constant<T_t0>::value, T_t0>;
335-
using T_sv_ref = ref_type_if_t<!is_constant<T_sv>::value, T_sv>;
336-
using T_sw_ref = ref_type_if_t<!is_constant<T_sw>::value, T_sw>;
337-
using T_st0_ref = ref_type_if_t<!is_constant<T_st0>::value, T_st0>;
330+
using T_y_ref = ref_type_t<T_y>;
331+
using T_a_ref = ref_type_t<T_a>;
332+
using T_v_ref = ref_type_t<T_v>;
333+
using T_w_ref = ref_type_t<T_w>;
334+
using T_t0_ref = ref_type_t<T_t0>;
335+
using T_sv_ref = ref_type_t<T_sv>;
336+
using T_sw_ref = ref_type_t<T_sw>;
337+
using T_st0_ref = ref_type_t<T_st0>;
338338

339339
using T_partials_return
340340
= partials_return_t<T_y, T_a, T_t0, T_w, T_v, T_sv, T_sw, T_st0>;
@@ -449,6 +449,9 @@ inline auto wiener_lpdf(const T_y& y, const T_a& a, const T_t0& t0,
449449
// calculate density and partials
450450
for (size_t i = 0; i < N; i++) {
451451
if (sw_vec[i] == 0 && st0_vec[i] == 0) {
452+
// note: because we're delegating to wiener5_lpdf,
453+
// we need to make sure is_constant is consistent between
454+
// our inputs and these
452455
result += wiener_lpdf<propto>(y_vec[i], a_vec[i], t0_vec[i], w_vec[i],
453456
v_vec[i], sv_vec[i], precision_derivatives);
454457
continue;

test/generate_expression_tests.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ def save_tests_in_files(N_files, tests):
2929
for i in range(N_files):
3030
start = i * len(tests) // N_files
3131
end = (i + 1) * len(tests) // N_files
32+
if start >= end:
33+
# don't try to compile an empty file
34+
continue
3235
with open(src_folder + "tests%d_test.cpp" % i, "w") as out:
3336
out.write("#include <test/expressions/expression_test_helpers.hpp>\n\n")
3437
for test in tests[start:end]:
@@ -125,5 +128,5 @@ def main(functions=(), j=1):
125128
code = cg.cpp(),
126129
)
127130
)
128-
131+
129132
save_tests_in_files(j, tests)

test/sig_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def get_cpp_type(stan_type):
132132
"uniform_lcdf": [None, 0.2, 0.9],
133133
"uniform_lpdf": [None, 0.2, 0.9],
134134
"uniform_rng": [0.2, 1.9, None],
135-
"wiener_lpdf": [0.8, None, 0.4, None, None],
135+
"wiener_lpdf": [0.8, None, 0.4, None, None, None, None, None],
136136
}
137137

138138
# list of functions we do not test. These are mainly functions implemented in compiler

0 commit comments

Comments
 (0)