1 #ifndef STAN_MATH_PRIM_FUN_POSITIVE_ORDERED_FREE_HPP
2 #define STAN_MATH_PRIM_FUN_POSITIVE_ORDERED_FREE_HPP
3 
4 #include <stan/math/prim/meta.hpp>
5 #include <stan/math/prim/err.hpp>
6 #include <stan/math/prim/fun/Eigen.hpp>
7 #include <stan/math/prim/fun/log.hpp>
8 #include <stan/math/prim/fun/to_ref.hpp>
9 #include <cmath>
10 
11 namespace stan {
12 namespace math {
13 
14 /**
15  * Return the vector of unconstrained scalars that transform to
16  * the specified positive ordered vector.
17  *
18  * <p>This function inverts the constraining operation defined in
19  * <code>positive_ordered_constrain(Matrix)</code>,
20  *
21  * @tparam T type of elements in the vector
22  * @param y Vector of positive, ordered scalars.
23  * @return Free vector that transforms into the input vector.
24  * @throw std::domain_error if y is not a vector of positive,
25  *   ordered scalars.
26  */
27 template <typename EigVec, require_eigen_col_vector_t<EigVec>* = nullptr>
positive_ordered_free(const EigVec & y)28 auto positive_ordered_free(const EigVec& y) {
29   using std::log;
30   const auto& y_ref = to_ref(y);
31   check_positive_ordered("stan::math::positive_ordered_free",
32                          "Positive ordered variable", y_ref);
33   Eigen::Index k = y_ref.size();
34   plain_type_t<EigVec> x(k);
35   if (k == 0) {
36     return x;
37   }
38   x.coeffRef(0) = log(y_ref.coeff(0));
39   x.tail(k - 1)
40       = (y_ref.tail(k - 1) - y_ref.head(k - 1)).array().log().matrix();
41   return x;
42 }
43 
44 /**
45  * Overload of `positive_ordered_free()` to untransform each Eigen vector
46  * in a standard vector.
47  * @tparam T A standard vector with with a `value_type` which inherits from
48  *  `Eigen::MatrixBase` with compile time rows or columns equal to 1.
49  * @param x The standard vector to untransform.
50  */
51 template <typename T, require_std_vector_t<T>* = nullptr>
positive_ordered_free(const T & x)52 auto positive_ordered_free(const T& x) {
53   return apply_vector_unary<T>::apply(
54       x, [](auto&& v) { return positive_ordered_free(v); });
55 }
56 
57 }  // namespace math
58 }  // namespace stan
59 
60 #endif
61