1 #ifndef STAN_MATH_PRIM_FUN_CORR_CONSTRAIN_HPP
2 #define STAN_MATH_PRIM_FUN_CORR_CONSTRAIN_HPP
3 
4 #include <stan/math/prim/meta.hpp>
5 #include <stan/math/prim/fun/log1m.hpp>
6 #include <stan/math/prim/fun/square.hpp>
7 #include <stan/math/prim/fun/sum.hpp>
8 #include <stan/math/prim/fun/tanh.hpp>
9 #include <cmath>
10 
11 namespace stan {
12 namespace math {
13 
14 /**
15  * Return the result of transforming the specified scalar or container of values
16  * to have a valid correlation value between -1 and 1 (inclusive).
17  *
18  * <p>The transform used is the hyperbolic tangent function,
19  *
20  * <p>\f$f(x) = \tanh x = \frac{\exp(2x) - 1}{\exp(2x) + 1}\f$.
21  *
22  * @tparam T type of value or container
23  * @param[in] x value or container
24  * @return tanh transform
25  */
26 template <typename T>
corr_constrain(const T & x)27 inline plain_type_t<T> corr_constrain(const T& x) {
28   return tanh(x);
29 }
30 
31 /**
32  * Return the result of transforming the specified scalar or container of values
33  * to have a valid correlation value between -1 and 1 (inclusive).
34  *
35  * <p>The transform used is as specified for
36  * <code>corr_constrain(T)</code>.  The log absolute Jacobian
37  * determinant is
38  *
39  * <p>\f$\log | \frac{d}{dx} \tanh x  | = \log (1 - \tanh^2 x)\f$.
40  *
41  * @tparam T_x Type of scalar or container
42  * @param[in] x value or container
43  * @param[in,out] lp log density accumulator
44  */
45 template <typename T_x, typename T_lp>
corr_constrain(const T_x & x,T_lp & lp)46 inline auto corr_constrain(const T_x& x, T_lp& lp) {
47   plain_type_t<T_x> tanh_x = tanh(x);
48   lp += sum(log1m(square(tanh_x)));
49   return tanh_x;
50 }
51 
52 /**
53  * Return the result of transforming the specified scalar or container of values
54  * to have a valid correlation value between -1 and 1 (inclusive). If the
55  * `Jacobian` parameter is `true`, the log density accumulator is incremented
56  * with the log absolute Jacobian determinant of the transform.  All of the
57  * transforms are specified with their Jacobians in the *Stan Reference Manual*
58  * chapter Constraint Transforms.
59  *
60  * @tparam Jacobian if `true`, increment log density accumulator with log
61  * absolute Jacobian determinant of constraining transform
62  * @tparam T_x Type of scalar or container
63  * @tparam T_lp type of target log density accumulator
64  * @param[in] x value or container
65  * @param[in,out] lp log density accumulator
66  */
67 template <bool Jacobian, typename T_x, typename T_lp>
corr_constrain(const T_x & x,T_lp & lp)68 inline auto corr_constrain(const T_x& x, T_lp& lp) {
69   if (Jacobian) {
70     return corr_constrain(x, lp);
71   } else {
72     return corr_constrain(x);
73   }
74 }
75 
76 }  // namespace math
77 }  // namespace stan
78 #endif
79