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)28auto 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)52auto 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