Skip to content

Commit b7ef5fa

Browse files
committed
Allow vector overloads to be called without lp argument
1 parent 1b7424b commit b7ef5fa

14 files changed

Lines changed: 287 additions & 340 deletions

stan/math/prim/constraint/cholesky_corr_constrain.hpp

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -77,32 +77,26 @@ cholesky_corr_constrain(const EigVec& y, int K, Lp& lp) {
7777
}
7878

7979
/**
80-
* Return The cholesky of a `KxK` correlation matrix. If the `Jacobian`
81-
* parameter is `true`, the log density accumulator is incremented with the log
82-
* absolute Jacobian determinant of the transform. All of the transforms are
83-
* specified with their Jacobians in the *Stan Reference Manual* chapter
84-
* Constraint Transforms.
85-
* @tparam Jacobian if `true`, increment log density accumulator with log
86-
* absolute Jacobian determinant of constraining transform
87-
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
88-
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
89-
* and 1 column
90-
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
91-
* convertable to this.
80+
* Return The cholesky of a `KxK` correlation matrix.
81+
* This overload handles looping over the elements of a standard vector.
82+
* @tparam T A standard vector with inner type inheriting from
83+
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
84+
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
85+
* @tparam Lp A pack that is either empty, or exactly one scalar type for the lp
86+
* argument. The scalar type of T should be convertable to this.
9287
* @param y Linearly Serialized vector of size `(K * (K - 1))/2` holding the
9388
* column major order elements of the lower triangurlar
9489
* @param K The size of the matrix to return
95-
* @param[in,out] lp log density accumulator
90+
* @param[in,out] lp log density accumulator or empty
9691
*/
97-
template <bool Jacobian, typename T, typename Lp,
98-
require_not_std_vector_t<T>* = nullptr,
99-
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
100-
inline auto cholesky_corr_constrain(const T& y, int K, Lp& lp) {
101-
if (Jacobian) {
102-
return cholesky_corr_constrain(y, K, lp);
103-
} else {
104-
return cholesky_corr_constrain(y, K);
105-
}
92+
template <typename T, typename... Lp, require_std_vector_t<T>* = nullptr>
93+
inline auto cholesky_corr_constrain(const T& y, int K, Lp&... lp) {
94+
static_assert(sizeof...(lp) == 0 || sizeof...(lp) == 1,
95+
"cholesky_corr_constrain should be called with either "
96+
"two or three arguments");
97+
return apply_vector_unary<T>::apply(y, [&lp..., K](auto&& v) {
98+
return cholesky_corr_constrain(v, K, lp...);
99+
});
106100
}
107101

108102
/**
@@ -113,9 +107,9 @@ inline auto cholesky_corr_constrain(const T& y, int K, Lp& lp) {
113107
* Constraint Transforms.
114108
* @tparam Jacobian if `true`, increment log density accumulator with log
115109
* absolute Jacobian determinant of constraining transform
116-
* @tparam T A standard vector with inner type inheriting from
117-
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
118-
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
110+
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
111+
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
112+
* and 1 column, or a standard vector thereof
119113
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
120114
* convertable to this.
121115
* @param y Linearly Serialized vector of size `(K * (K - 1))/2` holding the
@@ -124,12 +118,13 @@ inline auto cholesky_corr_constrain(const T& y, int K, Lp& lp) {
124118
* @param[in,out] lp log density accumulator
125119
*/
126120
template <bool Jacobian, typename T, typename Lp,
127-
require_std_vector_t<T>* = nullptr,
128121
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
129122
inline auto cholesky_corr_constrain(const T& y, int K, Lp& lp) {
130-
return apply_vector_unary<T>::apply(y, [&lp, K](auto&& v) {
131-
return cholesky_corr_constrain<Jacobian>(v, K, lp);
132-
});
123+
if constexpr (Jacobian) {
124+
return cholesky_corr_constrain(y, K, lp);
125+
} else {
126+
return cholesky_corr_constrain(y, K);
127+
}
133128
}
134129

135130
} // namespace math

stan/math/prim/constraint/cholesky_factor_constrain.hpp

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -89,34 +89,28 @@ cholesky_factor_constrain(const T& x, int M, int N, Lp& lp) {
8989
/**
9090
* Return the Cholesky factor of the specified size read from the specified
9191
* vector. A total of (N choose 2) + N + N * (M - N) free parameters are
92-
* required to read an M by N Cholesky factor. If the `Jacobian` parameter is
93-
* `true`, the log density accumulator is incremented with the log absolute
94-
* Jacobian determinant of the transform. All of the transforms are specified
95-
* with their Jacobians in the *Stan Reference Manual* chapter Constraint
96-
* Transforms.
92+
* required to read an M by N Cholesky factor.
93+
* This overload handles looping over the elements of a standard vector.
9794
*
98-
* @tparam Jacobian if `true`, increment log density accumulator with log
99-
* absolute Jacobian determinant of constraining transform
100-
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
101-
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
102-
* and 1 column
103-
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
104-
* convertable to this.
95+
* @tparam T A standard vector with inner type inheriting from
96+
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
97+
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
98+
* @tparam Lp A pack that is either empty, or exactly one scalar type for the lp
99+
* argument. The scalar type of T should be convertable to this.
105100
* @param x Vector of unconstrained values
106101
* @param M number of rows
107102
* @param N number of columns
108-
* @param[in,out] lp log density accumulator
103+
* @param[in,out] lp log density accumulator or empty
109104
* @return Cholesky factor
110105
*/
111-
template <bool Jacobian, typename T, typename Lp,
112-
require_not_std_vector_t<T>* = nullptr,
113-
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
114-
inline auto cholesky_factor_constrain(const T& x, int M, int N, Lp& lp) {
115-
if (Jacobian) {
116-
return cholesky_factor_constrain(x, M, N, lp);
117-
} else {
118-
return cholesky_factor_constrain(x, M, N);
119-
}
106+
template <typename T, typename... Lp, require_std_vector_t<T>* = nullptr>
107+
inline auto cholesky_factor_constrain(const T& x, int M, int N, Lp&... lp) {
108+
static_assert(sizeof...(lp) == 0 || sizeof...(lp) == 1,
109+
"cholesky_factor_constrain should be called with either "
110+
"three or four arguments");
111+
return apply_vector_unary<T>::apply(x, [&lp..., M, N](auto&& v) {
112+
return cholesky_factor_constrain(v, M, N, lp...);
113+
});
120114
}
121115

122116
/**
@@ -130,9 +124,9 @@ inline auto cholesky_factor_constrain(const T& x, int M, int N, Lp& lp) {
130124
*
131125
* @tparam Jacobian if `true`, increment log density accumulator with log
132126
* absolute Jacobian determinant of constraining transform
133-
* @tparam T A standard vector with inner type inheriting from
134-
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
135-
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
127+
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
128+
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
129+
* and 1 column
136130
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
137131
* convertable to this.
138132
* @param x Vector of unconstrained values
@@ -142,12 +136,13 @@ inline auto cholesky_factor_constrain(const T& x, int M, int N, Lp& lp) {
142136
* @return Cholesky factor
143137
*/
144138
template <bool Jacobian, typename T, typename Lp,
145-
require_std_vector_t<T>* = nullptr,
146139
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
147140
inline auto cholesky_factor_constrain(const T& x, int M, int N, Lp& lp) {
148-
return apply_vector_unary<T>::apply(x, [&lp, M, N](auto&& v) {
149-
return cholesky_factor_constrain<Jacobian>(v, M, N, lp);
150-
});
141+
if constexpr (Jacobian) {
142+
return cholesky_factor_constrain(x, M, N, lp);
143+
} else {
144+
return cholesky_factor_constrain(x, M, N);
145+
}
151146
}
152147

153148
} // namespace math

stan/math/prim/constraint/corr_matrix_constrain.hpp

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -82,31 +82,24 @@ corr_matrix_constrain(const T& x, Eigen::Index k, Lp& lp) {
8282
* the specified vector of unconstrained values. The input vector must be of
8383
* length \f${k \choose 2} = \frac{k(k-1)}{2}\f$. The values in the input
8484
* vector represent unconstrained (partial) correlations among the dimensions.
85-
* If the `Jacobian` parameter is `true`, the log density accumulator is
86-
* incremented with the log absolute Jacobian determinant of the transform. All
87-
* of the transforms are specified with their Jacobians in the *Stan Reference
88-
* Manual* chapter Constraint Transforms.
85+
* This overload handles looping over the elements of a standard vector.
8986
*
90-
* @tparam Jacobian if `true`, increment log density accumulator with log
91-
* absolute Jacobian determinant of constraining transform
92-
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
93-
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
94-
* and 1 column
95-
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
96-
* convertable to this.
97-
* @param x Vector of unconstrained partial correlations
98-
* @param k Dimensionality of returned correlation matrix
99-
* @param[in,out] lp log density accumulator
87+
* @tparam T A standard vector with inner type inheriting from
88+
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
89+
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
90+
* @tparam Lp A pack that is either empty, or exactly one scalar type for the lp
91+
* argument. The scalar type of T should be convertable to this.
92+
* @param y Vector of unconstrained partial correlations
93+
* @param K Dimensionality of returned correlation matrix
94+
* @param[in, out] lp log density accumulator or empty
10095
*/
101-
template <bool Jacobian, typename T, typename Lp,
102-
require_not_std_vector_t<T>* = nullptr,
103-
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
104-
inline auto corr_matrix_constrain(const T& x, Eigen::Index k, Lp& lp) {
105-
if (Jacobian) {
106-
return corr_matrix_constrain(x, k, lp);
107-
} else {
108-
return corr_matrix_constrain(x, k);
109-
}
96+
template <typename T, typename... Lp, require_std_vector_t<T>* = nullptr>
97+
inline auto corr_matrix_constrain(const T& y, int K, Lp&... lp) {
98+
static_assert(sizeof...(lp) == 0 || sizeof...(lp) == 1,
99+
"corr_matrix_constrain should be called with either "
100+
"two or three arguments");
101+
return apply_vector_unary<T>::apply(
102+
y, [&lp..., K](auto&& v) { return corr_matrix_constrain(v, K, lp...); });
110103
}
111104

112105
/**
@@ -121,22 +114,23 @@ inline auto corr_matrix_constrain(const T& x, Eigen::Index k, Lp& lp) {
121114
*
122115
* @tparam Jacobian if `true`, increment log density accumulator with log
123116
* absolute Jacobian determinant of constraining transform
124-
* @tparam T A standard vector with inner type inheriting from
125-
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
126-
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
117+
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
118+
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
119+
* and 1 column or standard vector thereof
127120
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
128121
* convertable to this.
129-
* @param y Vector of unconstrained partial correlations
130-
* @param K Dimensionality of returned correlation matrix
122+
* @param x Vector of unconstrained partial correlations
123+
* @param k Dimensionality of returned correlation matrix
131124
* @param[in,out] lp log density accumulator
132125
*/
133126
template <bool Jacobian, typename T, typename Lp,
134-
require_std_vector_t<T>* = nullptr,
135127
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
136-
inline auto corr_matrix_constrain(const T& y, int K, Lp& lp) {
137-
return apply_vector_unary<T>::apply(y, [&lp, K](auto&& v) {
138-
return corr_matrix_constrain<Jacobian>(v, K, lp);
139-
});
128+
inline auto corr_matrix_constrain(const T& x, Eigen::Index k, Lp& lp) {
129+
if constexpr (Jacobian) {
130+
return corr_matrix_constrain(x, k, lp);
131+
} else {
132+
return corr_matrix_constrain(x, k);
133+
}
140134
}
141135

142136
} // namespace math

stan/math/prim/constraint/cov_matrix_constrain.hpp

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -91,33 +91,26 @@ cov_matrix_constrain(const T& x, Eigen::Index K, Lp& lp) {
9191

9292
/**
9393
* Return the symmetric, positive-definite matrix of dimensions K by K resulting
94-
* from transforming the specified finite vector of size K plus (K choose 2). If
95-
* the `Jacobian` parameter is `true`, the log density accumulator is
96-
* incremented with the log absolute Jacobian determinant of the transform. All
97-
* of the transforms are specified with their Jacobians in the *Stan Reference
98-
* Manual* chapter Constraint Transforms.
94+
* from transforming the specified finite vector of size K plus (K choose 2).
95+
* This overload handles looping over the elements of a standard vector.
9996
*
100-
* @tparam Jacobian if `true`, increment log density accumulator with log
101-
* absolute Jacobian determinant of constraining transform
102-
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
103-
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
104-
* and 1 column
105-
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
106-
* convertable to this.
97+
* @tparam T A standard vector with inner type inheriting from
98+
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
99+
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
100+
* @tparam Lp A pack that is either empty, or exactly one scalar type for the lp
101+
* argument. The scalar type of T should be convertable to this.
107102
* @param x The vector to convert to a covariance matrix
108103
* @param K The dimensions of the resulting covariance matrix
109-
* @param[in, out] lp log density accumulator
104+
* @param[in, out] lp log density accumulator or empty
110105
* @throws std::domain_error if (x.size() != K + (K choose 2)).
111106
*/
112-
template <bool Jacobian, typename T, typename Lp,
113-
require_not_std_vector_t<T>* = nullptr,
114-
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
115-
inline auto cov_matrix_constrain(const T& x, Eigen::Index K, Lp& lp) {
116-
if (Jacobian) {
117-
return cov_matrix_constrain(x, K, lp);
118-
} else {
119-
return cov_matrix_constrain(x, K);
120-
}
107+
template <typename T, typename... Lp, require_std_vector_t<T>* = nullptr>
108+
inline auto cov_matrix_constrain(const T& x, Eigen::Index K, Lp&... lp) {
109+
static_assert(sizeof...(lp) == 0 || sizeof...(lp) == 1,
110+
"cov_matrix_constrain should be called with either "
111+
"two or three arguments");
112+
return apply_vector_unary<T>::apply(
113+
x, [&lp..., K](auto&& v) { return cov_matrix_constrain(v, K, lp...); });
121114
}
122115

123116
/**
@@ -130,9 +123,9 @@ inline auto cov_matrix_constrain(const T& x, Eigen::Index K, Lp& lp) {
130123
*
131124
* @tparam Jacobian if `true`, increment log density accumulator with log
132125
* absolute Jacobian determinant of constraining transform
133-
* @tparam T A standard vector with inner type inheriting from
134-
* `Eigen::DenseBase` or a `var_value` with inner type inheriting from
135-
* `Eigen::DenseBase` with compile time dynamic rows and 1 column
126+
* @tparam T A type inheriting from `Eigen::DenseBase` or a `var_value` with
127+
* inner type inheriting from `Eigen::DenseBase` with compile time dynamic rows
128+
* and 1 column, or standard vector thereof
136129
* @tparam Lp A scalar type for the lp argument. The scalar type of T should be
137130
* convertable to this.
138131
* @param x The vector to convert to a covariance matrix
@@ -141,12 +134,13 @@ inline auto cov_matrix_constrain(const T& x, Eigen::Index K, Lp& lp) {
141134
* @throws std::domain_error if (x.size() != K + (K choose 2)).
142135
*/
143136
template <bool Jacobian, typename T, typename Lp,
144-
require_std_vector_t<T>* = nullptr,
145137
require_convertible_t<return_type_t<T>, Lp>* = nullptr>
146138
inline auto cov_matrix_constrain(const T& x, Eigen::Index K, Lp& lp) {
147-
return apply_vector_unary<T>::apply(x, [&lp, K](auto&& v) {
148-
return cov_matrix_constrain<Jacobian>(v, K, lp);
149-
});
139+
if constexpr (Jacobian) {
140+
return cov_matrix_constrain(x, K, lp);
141+
} else {
142+
return cov_matrix_constrain(x, K);
143+
}
150144
}
151145

152146
} // namespace math

0 commit comments

Comments
 (0)