1 #ifndef STAN_MATH_PRIM_FUN_ORDERED_FREE_HPP 2 #define STAN_MATH_PRIM_FUN_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>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> ordered_free(const EigVec & y)28plain_type_t<EigVec> ordered_free(const EigVec& y) { 29 const auto& y_ref = to_ref(y); 30 check_ordered("stan::math::ordered_free", "Ordered variable", y_ref); 31 using std::log; 32 Eigen::Index k = y.size(); 33 plain_type_t<EigVec> x(k); 34 if (k == 0) { 35 return x; 36 } 37 x[0] = y_ref[0]; 38 for (Eigen::Index i = 1; i < k; ++i) { 39 x.coeffRef(i) = log(y_ref.coeff(i) - y_ref.coeff(i - 1)); 40 } 41 return x; 42 } 43 44 /** 45 * Overload of `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> ordered_free(const T & x)52auto ordered_free(const T& x) { 53 return apply_vector_unary<T>::apply(x, 54 [](auto&& v) { return ordered_free(v); }); 55 } 56 57 } // namespace math 58 } // namespace stan 59 60 #endif 61