1 #ifndef STAN_MATH_PRIM_FUN_LOG_INV_LOGIT_HPP 2 #define STAN_MATH_PRIM_FUN_LOG_INV_LOGIT_HPP 3 4 #include <stan/math/prim/meta.hpp> 5 #include <stan/math/prim/fun/exp.hpp> 6 #include <stan/math/prim/fun/log1p.hpp> 7 #include <stan/math/prim/functor/apply_scalar_unary.hpp> 8 #include <cmath> 9 10 namespace stan { 11 namespace math { 12 13 /** 14 * Returns the natural logarithm of the inverse logit of the 15 * specified argument. 16 * 17 \f[ 18 \mbox{log\_inv\_logit}(x) = 19 \begin{cases} 20 \ln\left(\frac{1}{1+\exp(-x)}\right)& \mbox{if } -\infty\leq x \leq \infty 21 \\[6pt] \textrm{NaN} & \mbox{if } x = \textrm{NaN} \end{cases} \f] 22 23 \f[ 24 \frac{\partial\, \mbox{log\_inv\_logit}(x)}{\partial x} = 25 \begin{cases} 26 \frac{1}{1+\exp(x)} & \mbox{if } -\infty\leq x\leq \infty \\[6pt] 27 \textrm{NaN} & \mbox{if } x = \textrm{NaN} 28 \end{cases} 29 \f] 30 * 31 * @param u argument 32 * @return log of the inverse logit of argument 33 */ log_inv_logit(double u)34inline double log_inv_logit(double u) { 35 using std::exp; 36 if (u < 0.0) { 37 return u - log1p(exp(u)); // prevent underflow 38 } 39 return -log1p(exp(-u)); 40 } 41 42 /** 43 * Returns the natural logarithm of the inverse logit of the 44 * specified argument. 45 * 46 * @param u argument 47 * @return log of the inverse logit of argument 48 */ log_inv_logit(int u)49inline double log_inv_logit(int u) { 50 return log_inv_logit(static_cast<double>(u)); 51 } 52 53 /** 54 * Structure to wrap log_inv_logit() so it can be vectorized. 55 */ 56 struct log_inv_logit_fun { 57 /** 58 * Return the natural logarithm of the inverse logit 59 * of the specified argument. 60 * 61 * @tparam T argument scalar type 62 * @param x argument 63 * @return natural log of inverse logit of argument 64 */ 65 template <typename T> funstan::math::log_inv_logit_fun66 static inline T fun(const T& x) { 67 return log_inv_logit(x); 68 } 69 }; 70 71 /** 72 * Return the elementwise application of 73 * <code>log_inv_logit()</code> to specified argument container. 74 * The return type promotes the underlying scalar argument type to 75 * double if it is an integer, and otherwise is the argument type. 76 * 77 * @tparam T type of container 78 * @param x container 79 * @return elementwise log_inv_logit of members of container 80 */ 81 template <typename T, 82 require_not_nonscalar_prim_or_rev_kernel_expression_t<T>* = nullptr> log_inv_logit(const T & x)83inline auto log_inv_logit(const T& x) { 84 return apply_scalar_unary<log_inv_logit_fun, T>::apply(x); 85 } 86 87 } // namespace math 88 } // namespace stan 89 90 #endif 91