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