Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds vectorized versions of the constrain functions #2580

Merged
merged 3 commits into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion stan/math/prim/fun/cholesky_corr_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,38 @@ cholesky_corr_constrain(const EigVec& y, int K, return_type_t<EigVec>& lp) {
* @param K The size of the matrix to return
* @param[in,out] lp log density accumulator
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto cholesky_corr_constrain(const T& y, int K, return_type_t<T>& lp) {
if (Jacobian) {
return cholesky_corr_constrain(y, K, lp);
} else {
return cholesky_corr_constrain(y, K);
}
}

/**
* Return The cholesky of a `KxK` correlation matrix. If the `Jacobian`
* parameter is `true`, the log density accumulator is incremented with the log
* absolute Jacobian determinant of the transform. All of the transforms are
* specified with their Jacobians in the *Stan Reference Manual* chapter
* Constraint Transforms.
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
* @param y Linearly Serialized vector of size `(K * (K - 1))/2` holding the
* column major order elements of the lower triangurlar
* @param K The size of the matrix to return
* @param[in,out] lp log density accumulator
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto cholesky_corr_constrain(const T& y, int K, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(y, [&lp, K](auto&& v) {
return cholesky_corr_constrain<Jacobian>(v, K, lp);
});
}

} // namespace math
} // namespace stan
#endif
30 changes: 29 additions & 1 deletion stan/math/prim/fun/cholesky_factor_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ cholesky_factor_constrain(const T& x, int M, int N, return_type_t<T>& lp) {
* @param[in,out] lp log density accumulator
* @return Cholesky factor
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto cholesky_factor_constrain(const T& x, int M, int N,
return_type_t<T>& lp) {
if (Jacobian) {
Expand All @@ -116,6 +116,34 @@ inline auto cholesky_factor_constrain(const T& x, int M, int N,
}
}

/**
* Return the Cholesky factor of the specified size read from the specified
* vector. A total of (N choose 2) + N + N * (M - N) free parameters are
* required to read an M by N Cholesky factor. If the `Jacobian` parameter is
* `true`, the log density accumulator is incremented with the log absolute
* Jacobian determinant of the transform. All of the transforms are specified
* with their Jacobians in the *Stan Reference Manual* chapter Constraint
* Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
* @param x Vector of unconstrained values
* @param M number of rows
* @param N number of columns
* @param[in,out] lp log density accumulator
* @return Cholesky factor
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto cholesky_factor_constrain(const T& x, int M, int N,
return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(x, [&lp, M, N](auto&& v) {
return cholesky_factor_constrain<Jacobian>(v, M, N, lp);
});
}

} // namespace math
} // namespace stan

Expand Down
28 changes: 27 additions & 1 deletion stan/math/prim/fun/corr_matrix_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ corr_matrix_constrain(const T& x, Eigen::Index k, return_type_t<T>& lp) {
* @param k Dimensionality of returned correlation matrix
* @param[in,out] lp log density accumulator
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto corr_matrix_constrain(const T& x, Eigen::Index k,
return_type_t<T>& lp) {
if (Jacobian) {
Expand All @@ -103,6 +103,32 @@ inline auto corr_matrix_constrain(const T& x, Eigen::Index k,
}
}

/**
* Return the correlation matrix of the specified dimensionality derived from
* the specified vector of unconstrained values. The input vector must be of
* length \f${k \choose 2} = \frac{k(k-1)}{2}\f$. The values in the input
* vector represent unconstrained (partial) correlations among the dimensions.
* If the `Jacobian` parameter is `true`, the log density accumulator is
* incremented with the log absolute Jacobian determinant of the transform. All
* of the transforms are specified with their Jacobians in the *Stan Reference
* Manual* chapter Constraint Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
* @param x Vector of unconstrained partial correlations
* @param k Dimensionality of returned correlation matrix
* @param[in,out] lp log density accumulator
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto corr_matrix_constrain(const T& y, int K, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(y, [&lp, K](auto&& v) {
return corr_matrix_constrain<Jacobian>(v, K, lp);
});
}

} // namespace math
} // namespace stan

Expand Down
28 changes: 27 additions & 1 deletion stan/math/prim/fun/cov_matrix_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ cov_matrix_constrain(const T& x, Eigen::Index K, return_type_t<T>& lp) {
* @param[in, out] lp log density accumulator
* @throws std::domain_error if (x.size() != K + (K choose 2)).
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto cov_matrix_constrain(const T& x, Eigen::Index K,
return_type_t<T>& lp) {
if (Jacobian) {
Expand All @@ -114,6 +114,32 @@ inline auto cov_matrix_constrain(const T& x, Eigen::Index K,
}
}

/**
* Return the symmetric, positive-definite matrix of dimensions K by K resulting
* from transforming the specified finite vector of size K plus (K choose 2). If
* the `Jacobian` parameter is `true`, the log density accumulator is
* incremented with the log absolute Jacobian determinant of the transform. All
* of the transforms are specified with their Jacobians in the *Stan Reference
* Manual* chapter Constraint Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
* @param x The vector to convert to a covariance matrix
* @param K The dimensions of the resulting covariance matrix
* @param[in, out] lp log density accumulator
* @throws std::domain_error if (x.size() != K + (K choose 2)).
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto cov_matrix_constrain(const T& x, Eigen::Index K,
return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(x, [&lp, K](auto&& v) {
return cov_matrix_constrain<Jacobian>(v, K, lp);
});
}

} // namespace math
} // namespace stan

Expand Down
30 changes: 29 additions & 1 deletion stan/math/prim/fun/cov_matrix_constrain_lkj.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ cov_matrix_constrain_lkj(const T& x, size_t k, return_type_t<T>& lp) {
* @return Covariance matrix derived from the unconstrained partial
* correlations and deviations.
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto cov_matrix_constrain_lkj(const T& x, size_t k,
return_type_t<T>& lp) {
if (Jacobian) {
Expand All @@ -93,6 +93,34 @@ inline auto cov_matrix_constrain_lkj(const T& x, size_t k,
}
}

/**
* Return the covariance matrix of the specified dimensionality derived from
* constraining the specified vector of unconstrained values. If the `Jacobian`
* parameter is `true`, the log density accumulator is incremented with the log
* absolute Jacobian determinant of the transform. All of the transforms are
* specified with their Jacobians in the *Stan Reference Manual* chapter
* Constraint Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time rows or columns equal to 1
* @param x Input vector of unconstrained partial correlations and
* standard deviations
* @param k Dimensionality of returned covariance matrix
* @param[in, out] lp log density accumulator
* @return Covariance matrix derived from the unconstrained partial
* correlations and deviations.
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto cov_matrix_constrain_lkj(const T& x, size_t k,
return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(x, [&lp, k](auto&& v) {
return cov_matrix_constrain_lkj<Jacobian>(v, k, lp);
});
}

} // namespace math
} // namespace stan

Expand Down
26 changes: 25 additions & 1 deletion stan/math/prim/fun/ordered_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ inline auto ordered_constrain(const EigVec& x, value_type_t<EigVec>& lp) {
* @param[in, out] lp log density accumulator
* @return Positive, increasing ordered vector.
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto ordered_constrain(const T& x, return_type_t<T>& lp) {
if (Jacobian) {
return ordered_constrain(x, lp);
Expand All @@ -86,6 +86,30 @@ inline auto ordered_constrain(const T& x, return_type_t<T>& lp) {
}
}

/**
* Return a positive valued, increasing ordered vector derived from the
* specified free vector. The returned constrained vector will have the same
* dimensionality as the specified free vector. If the `Jacobian` parameter is
* `true`, the log density accumulator is incremented with the log absolute
* Jacobian determinant of the transform. All of the transforms are specified
* with their Jacobians in the *Stan Reference Manual* chapter Constraint
* Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
* @param x Free vector of scalars
* @param[in, out] lp log density accumulator
* @return Positive, increasing ordered vector.
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto ordered_constrain(const T& x, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(
x, [&lp](auto&& v) { return ordered_constrain<Jacobian>(v, lp); });
}

} // namespace math
} // namespace stan

Expand Down
24 changes: 23 additions & 1 deletion stan/math/prim/fun/positive_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ inline auto positive_constrain(const T& x, S& lp) {
* @param[in, out] lp log density accumulator
* @return positive constrained version of unconstrained value(s)
*/
template <bool Jacobian, typename T>
template <bool Jacobian, typename T, require_not_std_vector_t<T>* = nullptr>
inline auto positive_constrain(const T& x, return_type_t<T>& lp) {
if (Jacobian) {
return positive_constrain(x, lp);
Expand All @@ -70,6 +70,28 @@ inline auto positive_constrain(const T& x, return_type_t<T>& lp) {
}
}

/**
* Return the positive value for the specified unconstrained input. If the
* `Jacobian` parameter is `true`, the log density accumulator is incremented
* with the log absolute Jacobian determinant of the transform. All of the
* transforms are specified with their Jacobians in the *Stan Reference Manual*
* chapter Constraint Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam T A standard vector with inner type inheriting from
* `Eigen::EigenBase`, a `var_value` with inner type inheriting from
* `Eigen::EigenBase`, a standard vector, or a scalar
* @param x unconstrained value or container
* @param[in, out] lp log density accumulator
* @return positive constrained version of unconstrained value(s)
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto positive_constrain(const T& x, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(
x, [&lp](auto&& v) { return positive_constrain<Jacobian>(v, lp); });
}

} // namespace math
} // namespace stan

Expand Down
1 change: 0 additions & 1 deletion stan/math/prim/fun/positive_free.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ namespace math {
*/
template <typename T>
inline T positive_free(const T& y) {
using std::log;
check_positive("positive_free", "Positive variable", y);
return log(y);
}
Expand Down
27 changes: 26 additions & 1 deletion stan/math/prim/fun/positive_ordered_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ inline auto positive_ordered_constrain(const Vec& x, return_type_t<Vec>& lp) {
* @param[in, out] lp log density accumulato
* @return Positive, increasing ordered vector
*/
template <bool Jacobian, typename Vec>
template <bool Jacobian, typename Vec, require_not_std_vector_t<Vec>* = nullptr>
inline auto positive_ordered_constrain(const Vec& x, return_type_t<Vec>& lp) {
if (Jacobian) {
return positive_ordered_constrain(x, lp);
Expand All @@ -81,6 +81,31 @@ inline auto positive_ordered_constrain(const Vec& x, return_type_t<Vec>& lp) {
}
}

/**
* Return a positive valued, increasing positive ordered vector derived from the
* specified free vector. The returned constrained vector will have the same
* dimensionality as the specified free vector. If the `Jacobian` parameter is
* `true`, the log density accumulator is incremented with the log absolute
* Jacobian determinant of the transform. All of the transforms are specified
* with their Jacobians in the *Stan Reference Manual* chapter Constraint
* Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam Vec A standard vector with inner type inheriting from
* `Eigen::EigenBase`, a `var_value` with inner type inheriting from
* `Eigen::EigenBase`
* @param x Free vector of scalars
* @param[in, out] lp log density accumulato
* @return Positive, increasing ordered vector
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto positive_ordered_constrain(const T& x, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(x, [&lp](auto&& v) {
return positive_ordered_constrain<Jacobian>(v, lp);
});
}

} // namespace math
} // namespace stan

Expand Down
24 changes: 23 additions & 1 deletion stan/math/prim/fun/simplex_constrain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ inline auto simplex_constrain(const Vec& y, value_type_t<Vec>& lp) {
* @param[in, out] lp log density accumulator
* @return simplex of dimensionality one greater than `y`
*/
template <bool Jacobian, typename Vec>
template <bool Jacobian, typename Vec, require_not_std_vector_t<Vec>* = nullptr>
auto simplex_constrain(const Vec& y, return_type_t<Vec>& lp) {
if (Jacobian) {
return simplex_constrain(y, lp);
Expand All @@ -106,6 +106,28 @@ auto simplex_constrain(const Vec& y, return_type_t<Vec>& lp) {
}
}

/**
* Return the simplex corresponding to the specified free vector. If the
* `Jacobian` parameter is `true`, the log density accumulator is incremented
* with the log absolute Jacobian determinant of the transform. All of the
* transforms are specified with their Jacobians in the *Stan Reference Manual*
* chapter Constraint Transforms.
*
* @tparam Jacobian if `true`, increment log density accumulator with log
* absolute Jacobian determinant of constraining transform
* @tparam Vec A standard vector with inner type inheriting from
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
* @param[in] y free vector
* @param[in, out] lp log density accumulator
* @return simplex of dimensionality one greater than `y`
*/
template <bool Jacobian, typename T, require_std_vector_t<T>* = nullptr>
inline auto simplex_constrain(const T& y, return_type_t<T>& lp) {
return apply_vector_unary<T>::apply(
y, [&lp](auto&& v) { return simplex_constrain<Jacobian>(v, lp); });
}

} // namespace math
} // namespace stan

Expand Down
Loading