1 #ifndef STAN_MATH_PRIM_FUN_LOG1M_HPP 2 #define STAN_MATH_PRIM_FUN_LOG1M_HPP 3 4 #include <stan/math/prim/meta.hpp> 5 #include <stan/math/prim/err.hpp> 6 #include <stan/math/prim/fun/is_nan.hpp> 7 #include <stan/math/prim/fun/log1p.hpp> 8 #include <stan/math/prim/functor/apply_scalar_unary.hpp> 9 10 namespace stan { 11 namespace math { 12 13 /** 14 * Return the natural logarithm of one minus the specified value. 15 * 16 * The main use of this function is to cut down on intermediate 17 * values during algorithmic differentiation. 18 * 19 \f[ 20 \mbox{log1m}(x) = 21 \begin{cases} 22 \ln(1-x) & \mbox{if } x \leq 1 \\ 23 \textrm{NaN} & \mbox{if } x > 1\\[6pt] 24 \textrm{NaN} & \mbox{if } x = \textrm{NaN} 25 \end{cases} 26 \f] 27 28 \f[ 29 \frac{\partial\, \mbox{log1m}(x)}{\partial x} = 30 \begin{cases} 31 -\frac{1}{1-x} & \mbox{if } x \leq 1 \\ 32 \textrm{NaN} & \mbox{if } x > 1\\[6pt] 33 \textrm{NaN} & \mbox{if } x = \textrm{NaN} 34 \end{cases} 35 \f] 36 * 37 * @param[in] x Argument. 38 * @return Natural log of one minus the argument. 39 * @throw <code>std::domain_error</code> If the argument is greater than 1. 40 * @throw <code>std::overflow_error</code> If the computation overflows. 41 */ log1m(double x)42inline double log1m(double x) { 43 if (!is_nan(x)) { 44 check_less_or_equal("log1m", "x", x, 1); 45 } 46 return stan::math::log1p(-x); 47 } 48 49 /** 50 * Structure to wrap log1m() so it can be vectorized. 51 * 52 * @tparam T type of variable 53 * @param x variable 54 * @return Natural log of (1 - x). 55 */ 56 struct log1m_fun { 57 template <typename T> funstan::math::log1m_fun58 static inline T fun(const T& x) { 59 return log1m(x); 60 } 61 }; 62 63 /** 64 * Vectorized version of log1m(). 65 * 66 * @tparam T type of container 67 * @param x container 68 * @return Natural log of 1 minus each value in x. 69 */ 70 template < 71 typename T, require_not_var_matrix_t<T>* = nullptr, 72 require_all_not_nonscalar_prim_or_rev_kernel_expression_t<T>* = nullptr> log1m(const T & x)73inline auto log1m(const T& x) { 74 return apply_scalar_unary<log1m_fun, T>::apply(x); 75 } 76 77 } // namespace math 78 } // namespace stan 79 80 #endif 81