2323#include < stan/math/prim/functor/partials_propagator.hpp>
2424#include < cmath>
2525#include < optional>
26+
2627namespace stan {
2728namespace math {
2829namespace internal {
@@ -31,11 +32,12 @@ namespace internal {
3132 * Computes log q and d(log q) / d(alpha) using continued fraction.
3233 */
3334template <bool any_fvar, bool partials_fvar, typename T_shape, typename T1, typename T2>
34- inline auto eval_q_cf (const T1& alpha, const T2& beta_y) {
35+ inline std::optional<std::pair<return_type_t <T1, T2>, return_type_t <T1, T2>>>
36+ eval_q_cf (const T1& alpha, const T2& beta_y) {
3537 using scalar_t = return_type_t <T1, T2>;
3638 using ret_t = std::pair<scalar_t , scalar_t >;
3739 if constexpr (!any_fvar && is_autodiff_v<T_shape>) {
38- auto log_q_result
40+ std::pair< double , double > log_q_result
3941 = log_gamma_q_dgamma (value_of_rec (alpha), value_of_rec (beta_y));
4042 if (likely (std::isfinite (value_of_rec (log_q_result.first )))) {
4143 return std::optional{log_q_result};
@@ -69,7 +71,8 @@ inline auto eval_q_cf(const T1& alpha, const T2& beta_y) {
6971 * Computes log q and d(log q) / d(alpha) using log1m.
7072 */
7173template <bool partials_fvar, typename T_shape, typename T1, typename T2>
72- inline auto eval_q_log1m (const T1& alpha, const T2& beta_y) {
74+ inline std::optional<std::pair<return_type_t <T1, T2>, return_type_t <T1, T2>>>
75+ eval_q_log1m (const T1& alpha, const T2& beta_y) {
7376 using scalar_t = return_type_t <T1, T2>;
7477 using ret_t = std::pair<scalar_t , scalar_t >;
7578 ret_t out{log1m (gamma_p (alpha, beta_y)), 0.0 };
@@ -132,18 +135,18 @@ inline return_type_t<T_y, T_shape, T_inv_scale> gamma_lccdf(
132135 for (size_t n = 0 ; n < N; n++) {
133136 // Explicit results for extreme values
134137 // The gradients are technically ill-defined, but treated as zero
135- const auto y_val = y_vec.val (n);
138+ const T_partials_return y_val = y_vec.val (n);
136139 if (y_val == 0.0 ) {
137140 continue ;
138141 }
139142 if (y_val == INFTY) {
140143 return ops_partials.build (negative_infinity ());
141144 }
142145
143- const auto alpha_val = alpha_vec.val (n);
144- const auto beta_val = beta_vec.val (n);
146+ const T_partials_return alpha_val = alpha_vec.val (n);
147+ const T_partials_return beta_val = beta_vec.val (n);
145148
146- const auto beta_y = beta_val * y_val;
149+ const T_partials_return beta_y = beta_val * y_val;
147150 if (beta_y == INFTY) {
148151 return ops_partials.build (negative_infinity ());
149152 }
@@ -164,14 +167,14 @@ inline return_type_t<T_y, T_shape, T_inv_scale> gamma_lccdf(
164167 P += result->first ;
165168
166169 if constexpr (is_autodiff_v<T_y> || is_autodiff_v<T_inv_scale>) {
167- const auto log_y = log (y_val);
168- const auto alpha_minus_one = fma (alpha_val, log_y, -log_y);
170+ const T_partials_return log_y = log (y_val);
171+ const T_partials_return alpha_minus_one = fma (alpha_val, log_y, -log_y);
169172
170- const auto log_pdf = alpha_val * log (beta_val)
173+ const T_partials_return log_pdf = alpha_val * log (beta_val)
171174 - lgamma (alpha_val) + alpha_minus_one
172175 - beta_y;
173176
174- const auto hazard = exp (log_pdf - result->first ); // f/Q
177+ const T_partials_return hazard = exp (log_pdf - result->first ); // f/Q
175178
176179 if constexpr (is_autodiff_v<T_y>) {
177180 partials<0 >(ops_partials)[n] -= hazard;
0 commit comments