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