1 #ifndef STAN_MATH_PRIM_FUN_TAN_HPP
2 #define STAN_MATH_PRIM_FUN_TAN_HPP
3 
4 #include <stan/math/prim/meta.hpp>
5 #include <stan/math/prim/fun/Eigen.hpp>
6 #include <stan/math/prim/fun/i_times.hpp>
7 #include <stan/math/prim/fun/tanh.hpp>
8 #include <stan/math/prim/functor/apply_scalar_unary.hpp>
9 #include <stan/math/prim/functor/apply_vector_unary.hpp>
10 #include <cmath>
11 #include <complex>
12 
13 namespace stan {
14 namespace math {
15 
16 /**
17  * Structure to wrap `tan()` so that it can be vectorized.
18  *
19  * @tparam T type of argument
20  * @param x angle in radians
21  * @return Tangent of x.
22  */
23 struct tan_fun {
24   template <typename T>
funstan::math::tan_fun25   static inline T fun(const T& x) {
26     using std::tan;
27     return tan(x);
28   }
29 };
30 
31 /**
32  * Vectorized version of `tan()`.
33  *
34  * @tparam Container type of container
35  * @param x angles in radians
36  * @return Tangent of each value in x.
37  */
38 template <typename Container,
39           require_not_container_st<std::is_arithmetic, Container>* = nullptr,
40           require_not_var_matrix_t<Container>* = nullptr,
41           require_all_not_nonscalar_prim_or_rev_kernel_expression_t<
42               Container>* = nullptr>
tan(const Container & x)43 inline auto tan(const Container& x) {
44   return apply_scalar_unary<tan_fun, Container>::apply(x);
45 }
46 
47 /**
48  * Version of `tan()` that accepts std::vectors, Eigen Matrix/Array objects
49  *  or expressions, and containers of these.
50  *
51  * @tparam Container Type of x
52  * @param x Container
53  * @return Tangent of each value in x.
54  */
55 template <typename Container,
56           require_container_st<std::is_arithmetic, Container>* = nullptr>
tan(const Container & x)57 inline auto tan(const Container& x) {
58   return apply_vector_unary<Container>::apply(
59       x, [](const auto& v) { return v.array().tan(); });
60 }
61 
62 namespace internal {
63 /**
64  * Return the tangent of the complex argument.
65  *
66  * @tparam V value type of argument
67  * @param[in] z argument
68  * @return tangent of the argument
69  */
70 template <typename V>
complex_tan(const std::complex<V> & z)71 inline std::complex<V> complex_tan(const std::complex<V>& z) {
72   return neg_i_times(tanh(i_times(z)));
73 }
74 }  // namespace internal
75 
76 }  // namespace math
77 }  // namespace stan
78 
79 #endif
80