1 #ifndef STAN_MATH_REV_FUN_ATANH_HPP 2 #define STAN_MATH_REV_FUN_ATANH_HPP 3 4 #include <stan/math/prim/fun/atanh.hpp> 5 #include <stan/math/rev/meta.hpp> 6 #include <stan/math/rev/core.hpp> 7 #include <stan/math/rev/fun/value_of_rec.hpp> 8 #include <stan/math/rev/fun/atan2.hpp> 9 #include <stan/math/rev/fun/cosh.hpp> 10 #include <stan/math/rev/fun/log.hpp> 11 #include <stan/math/rev/fun/sinh.hpp> 12 #include <stan/math/rev/fun/hypot.hpp> 13 #include <cmath> 14 #include <complex> 15 16 namespace stan { 17 namespace math { 18 19 /** 20 * The inverse hyperbolic tangent function for variables (C99). 21 * 22 * The derivative is defined by 23 * 24 * \f$\frac{d}{dx} \mbox{atanh}(x) = \frac{1}{1 - x^2}\f$. 25 * 26 \f[ 27 \mbox{atanh}(x) = 28 \begin{cases} 29 \textrm{NaN} & \mbox{if } x < -1\\ 30 \tanh^{-1}(x) & \mbox{if } -1\leq x \leq 1 \\ 31 \textrm{NaN} & \mbox{if } x > 1\\[6pt] 32 \textrm{NaN} & \mbox{if } x = \textrm{NaN} 33 \end{cases} 34 \f] 35 36 \f[ 37 \frac{\partial\, \mbox{atanh}(x)}{\partial x} = 38 \begin{cases} 39 \textrm{NaN} & \mbox{if } x < -1\\ 40 \frac{\partial\, \tanh^{-1}(x)}{\partial x} & \mbox{if } -1\leq x\leq 1 \\ 41 \textrm{NaN} & \mbox{if } x > 1\\[6pt] 42 \textrm{NaN} & \mbox{if } x = \textrm{NaN} 43 \end{cases} 44 \f] 45 46 \f[ 47 \tanh^{-1}(x)=\frac{1}{2}\ln\left(\frac{1+x}{1-x}\right) 48 \f] 49 50 \f[ 51 \frac{\partial \, \tanh^{-1}(x)}{\partial x} = \frac{1}{1-x^2} 52 \f] 53 * 54 * @param x The variable. 55 * @return Inverse hyperbolic tangent of the variable. 56 * @throw std::domain_error if a < -1 or a > 1 57 */ atanh(const var & x)58inline var atanh(const var& x) { 59 return make_callback_var(atanh(x.val()), [x](const auto& vi) mutable { 60 x.adj() += vi.adj() / (1.0 - x.val() * x.val()); 61 }); 62 } 63 64 /** 65 * The inverse hyperbolic tangent function for variables (C99). 66 * 67 * @tparam Varmat a `var_value` with inner Eigen type 68 * @param x The variable. 69 * @return Inverse hyperbolic tangent of the variable. 70 * @throw std::domain_error if a < -1 or a > 1 71 */ 72 template <typename VarMat, require_var_matrix_t<VarMat>* = nullptr> atanh(const VarMat & x)73inline auto atanh(const VarMat& x) { 74 return make_callback_var( 75 x.val().unaryExpr([](const auto x) { return atanh(x); }), 76 [x](const auto& vi) mutable { 77 x.adj().array() += vi.adj().array() / (1.0 - x.val().array().square()); 78 }); 79 } 80 81 /** 82 * Return the hyperbolic arc tangent of the complex argument. 83 * 84 * @param[in] z argument 85 * @return hyperbolic arc tangent of the argument 86 */ atanh(const std::complex<var> & z)87inline std::complex<var> atanh(const std::complex<var>& z) { 88 return stan::math::internal::complex_atanh(z); 89 } 90 91 } // namespace math 92 } // namespace stan 93 #endif 94