1 #ifndef STAN_MATH_PRIM_FUN_ACOS_HPP
2 #define STAN_MATH_PRIM_FUN_ACOS_HPP
3
4 #include <stan/math/prim/core.hpp>
5 #include <stan/math/prim/meta.hpp>
6 #include <stan/math/prim/fun/asin.hpp>
7 #include <stan/math/prim/fun/constants.hpp>
8 #include <stan/math/prim/fun/Eigen.hpp>
9 #include <stan/math/prim/fun/isinf.hpp>
10 #include <stan/math/prim/fun/isfinite.hpp>
11 #include <stan/math/prim/fun/isnan.hpp>
12 #include <stan/math/prim/fun/polar.hpp>
13 #include <stan/math/prim/functor/apply_scalar_unary.hpp>
14 #include <stan/math/prim/functor/apply_vector_unary.hpp>
15 #include <cmath>
16 #include <complex>
17
18 namespace stan {
19 namespace math {
20
21 /**
22 * Structure to wrap `acos()` so it can be vectorized.
23 *
24 * @tparam T type of variable
25 * @param x argument
26 * @return Arc cosine of variable in radians.
27 */
28 struct acos_fun {
29 template <typename T>
funstan::math::acos_fun30 static inline T fun(const T& x) {
31 using std::acos;
32 return acos(x);
33 }
34 };
35
36 /**
37 * Returns the elementwise `acos()` of the input,
38 * which may be a scalar or any Stan container of numeric scalars.
39 *
40 * @tparam Container type of container
41 * @param x argument
42 * @return Arc cosine of each variable in the container, in radians.
43 */
44 template <typename Container,
45 require_not_container_st<std::is_arithmetic, Container>* = nullptr,
46 require_not_var_matrix_t<Container>* = nullptr,
47 require_all_not_nonscalar_prim_or_rev_kernel_expression_t<
48 Container>* = nullptr>
acos(const Container & x)49 inline auto acos(const Container& x) {
50 return apply_scalar_unary<acos_fun, Container>::apply(x);
51 }
52
53 /**
54 * Version of `acos()` that accepts std::vectors, Eigen Matrix/Array objects
55 * or expressions, and containers of these.
56 *
57 * @tparam Container Type of x
58 * @param x argument
59 * @return Arc cosine of each variable in the container, in radians.
60 */
61 template <typename Container,
62 require_container_st<std::is_arithmetic, Container>* = nullptr>
acos(const Container & x)63 inline auto acos(const Container& x) {
64 return apply_vector_unary<Container>::apply(
65 x, [](const auto& v) { return v.array().acos(); });
66 }
67
68 namespace internal {
69 /**
70 * Return the arc cosine of the complex argument.
71 *
72 * @tparam V value type of argument
73 * @param[in] x argument
74 * @return arc cosine of the argument
75 */
76 template <typename V>
complex_acos(const std::complex<V> & x)77 inline std::complex<V> complex_acos(const std::complex<V>& x) {
78 return 0.5 * pi() - asin(x);
79 }
80 } // namespace internal
81
82 } // namespace math
83 } // namespace stan
84
85 #endif
86