@@ -49,15 +49,14 @@ namespace math {
4949 * @return Inverse logit of argument.
5050 */
5151inline double inv_logit (double a) {
52- using std::exp;
5352 if (a < 0 ) {
54- double exp_a = exp (a);
53+ double exp_a = std:: exp (a);
5554 if (a < LOG_EPSILON) {
5655 return exp_a;
5756 }
58- return exp_a / (1 + exp_a);
57+ return exp_a / (1.0 + exp_a);
5958 }
60- return inv (1 + exp (-a));
59+ return inv (1 + std:: exp (-a));
6160}
6261
6362/* *
@@ -69,28 +68,46 @@ inline double inv_logit(double a) {
6968 */
7069struct inv_logit_fun {
7170 template <typename T>
72- static inline auto fun (const T & x) {
73- return inv_logit (x );
71+ static inline auto fun (T& & x) {
72+ return inv_logit (std::forward<T>(x) );
7473 }
7574};
7675
7776/* *
78- * Vectorized version of inv_logit().
77+ * Vectorized version of inv_logit() for containers containing ad types .
7978 *
80- * @tparam T type of container
81- * @param x container
79+ * @tparam T type of std::vector
80+ * @param x std::vector
8281 * @return Inverse logit applied to each value in x.
8382 */
84- template <
85- typename T, require_not_var_matrix_t <T>* = nullptr ,
86- require_all_not_nonscalar_prim_or_rev_kernel_expression_t <T>* = nullptr >
87- inline auto inv_logit (const T& x) {
88- return apply_scalar_unary<inv_logit_fun, T>::apply (x);
83+ template <typename Container, require_ad_container_t <Container>* = nullptr ,
84+ require_all_not_nonscalar_prim_or_rev_kernel_expression_t <
85+ Container>* = nullptr ,
86+ require_not_rev_matrix_t <Container>* = nullptr >
87+ inline auto inv_logit (Container&& x) {
88+ return apply_scalar_unary<inv_logit_fun, Container>::apply (
89+ std::forward<Container>(x));
8990}
9091
91- // TODO(Tadej): Eigen is introducing their implementation logistic() of this
92- // in 3.4. Use that once we switch to Eigen 3.4
93-
92+ /* *
93+ * Vectorized version of inv_logit() for containers with arithmetic scalar
94+ * types.
95+ *
96+ * @tparam T A type of either `std::vector` or a type that directly inherits
97+ * from `Eigen::DenseBase`. The inner scalar type must not have an auto diff
98+ * scalar type.
99+ * @param x Eigen expression
100+ * @return Inverse logit applied to each value in x.
101+ */
102+ template <typename Container,
103+ require_container_bt<std::is_arithmetic, Container>* = nullptr ,
104+ require_all_not_nonscalar_prim_or_rev_kernel_expression_t <
105+ Container>* = nullptr >
106+ inline auto inv_logit (Container&& x) {
107+ return apply_vector_unary<Container>::apply (
108+ std::forward<Container>(x),
109+ [](const auto & v) { return v.array ().logistic (); });
110+ }
94111} // namespace math
95112} // namespace stan
96113
0 commit comments