Skip to content

Commit 04fe232

Browse files
committed
fix all places with Eigen maps and size functions for perfect forwarding
1 parent bb37bf9 commit 04fe232

6 files changed

Lines changed: 35 additions & 46 deletions

File tree

stan/math/prim/constraint/lb_free.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ template <typename T, typename L, require_all_eigen_t<T, L>* = nullptr>
5757
inline auto lb_free(T&& y, L&& lb) {
5858
auto&& y_ref = to_ref(std::forward<T>(y));
5959
auto&& lb_ref = to_ref(std::forward<L>(lb));
60-
promote_scalar_t<return_type_t<T, L>, T> ret(y.rows(), y.cols());
61-
for (Eigen::Index j = 0; j < y.cols(); ++j) {
62-
for (Eigen::Index i = 0; i < y.rows(); ++i) {
60+
promote_scalar_t<return_type_t<T, L>, T> ret(y_ref.rows(), y_ref.cols());
61+
for (Eigen::Index j = 0; j < y_ref.cols(); ++j) {
62+
for (Eigen::Index i = 0; i < y_ref.rows(); ++i) {
6363
ret.coeffRef(i, j) = lb_free(y_ref.coeff(i, j), lb_ref.coeff(i, j));
6464
}
6565
}

stan/math/prim/constraint/lub_free.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ inline auto lub_free(T&& y, L&& lb, U&& ub) {
7272
check_matching_dims("lub_free", "y", y, "lb", lb);
7373
auto&& y_ref = to_ref(std::forward<T>(y));
7474
auto&& lb_ref = to_ref(std::forward<L>(lb));
75-
promote_scalar_t<return_type_t<T, L, U>, T> ret(y.rows(), y.cols());
76-
for (Eigen::Index j = 0; j < y.cols(); ++j) {
77-
for (Eigen::Index i = 0; i < y.rows(); ++i) {
75+
promote_scalar_t<return_type_t<T, L, U>, T> ret(y_ref.rows(), y_ref.cols());
76+
for (Eigen::Index j = 0; j < y_ref.cols(); ++j) {
77+
for (Eigen::Index i = 0; i < y_ref.rows(); ++i) {
7878
ret.coeffRef(i, j) = lub_free(y_ref.coeff(i, j), lb_ref.coeff(i, j), ub);
7979
}
8080
}
@@ -92,9 +92,9 @@ inline auto lub_free(T&& y, L&& lb, U&& ub) {
9292
check_matching_dims("lub_free", "y", y, "ub", ub);
9393
auto&& y_ref = to_ref(std::forward<T>(y));
9494
auto&& ub_ref = to_ref(std::forward<U>(ub));
95-
promote_scalar_t<return_type_t<T, L, U>, T> ret(y.rows(), y.cols());
96-
for (Eigen::Index j = 0; j < y.cols(); ++j) {
97-
for (Eigen::Index i = 0; i < y.rows(); ++i) {
95+
promote_scalar_t<return_type_t<T, L, U>, T> ret(y_ref.rows(), y_ref.cols());
96+
for (Eigen::Index j = 0; j < y_ref.cols(); ++j) {
97+
for (Eigen::Index i = 0; i < y_ref.rows(); ++i) {
9898
ret.coeffRef(i, j) = lub_free(y_ref.coeff(i, j), lb, ub_ref.coeff(i, j));
9999
}
100100
}
@@ -113,9 +113,9 @@ inline auto lub_free(T&& y, L&& lb, U&& ub) {
113113
auto&& y_ref = to_ref(std::forward<T>(y));
114114
auto&& lb_ref = to_ref(std::forward<L>(lb));
115115
auto&& ub_ref = to_ref(std::forward<U>(ub));
116-
promote_scalar_t<return_type_t<T, L, U>, T> ret(y.rows(), y.cols());
117-
for (Eigen::Index j = 0; j < y.cols(); ++j) {
118-
for (Eigen::Index i = 0; i < y.rows(); ++i) {
116+
promote_scalar_t<return_type_t<T, L, U>, T> ret(y_ref.rows(), y_ref.cols());
117+
for (Eigen::Index j = 0; j < y_ref.cols(); ++j) {
118+
for (Eigen::Index i = 0; i < y_ref.rows(); ++i) {
119119
ret.coeffRef(i, j)
120120
= lub_free(y_ref.coeff(i, j), lb_ref.coeff(i, j), ub_ref.coeff(i, j));
121121
}

stan/math/prim/constraint/ub_free.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ inline auto ub_free(T&& y, U&& ub) {
6464
check_matching_dims("ub_free", "y", y, "ub", ub);
6565
auto&& y_ref = to_ref(std::forward<T>(y));
6666
auto&& ub_ref = to_ref(std::forward<U>(ub));
67-
promote_scalar_t<return_type_t<T, U>, T> ret(y.rows(), y.cols());
68-
for (Eigen::Index j = 0; j < y.cols(); ++j) {
69-
for (Eigen::Index i = 0; i < y.rows(); ++i) {
67+
promote_scalar_t<return_type_t<T, U>, T> ret(y_ref.rows(), y_ref.cols());
68+
for (Eigen::Index j = 0; j < y_ref.cols(); ++j) {
69+
for (Eigen::Index i = 0; i < y_ref.rows(); ++i) {
7070
ret.coeffRef(i, j) = ub_free(y_ref.coeff(i, j), ub_ref.coeff(i, j));
7171
}
7272
}

stan/math/prim/fun/to_matrix.hpp

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -126,36 +126,21 @@ to_matrix(EigMat&& x, int m, int n) {
126126
* @throw <code>std::invalid_argument</code>
127127
* if the sizes do not match
128128
*/
129-
template <typename T>
130-
inline auto to_matrix(const std::vector<T>& x, int m, int n) {
129+
template <typename T, require_std_vector_vt<is_stan_scalar, T>* = nullptr>
130+
inline auto to_matrix(T&& x, int m, int n) {
131131
static constexpr const char* function = "to_matrix(array)";
132132
check_size_match(function, "rows * columns", m * n, "vector size", x.size());
133-
return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>>(
134-
&x[0], m, n);
133+
return make_holder([m, n](auto&& x_) {
134+
if constexpr (std::is_integral_v<value_type_t<decltype(x_)>>) {
135+
return Eigen::Map<const Eigen::Matrix<value_type_t<decltype(x_)>, Eigen::Dynamic, Eigen::Dynamic>>(
136+
&x_[0], m, n).template cast<double>();
137+
} else {
138+
return Eigen::Map<const Eigen::Matrix<value_type_t<decltype(x_)>, Eigen::Dynamic, Eigen::Dynamic>>(
139+
&x_[0], m, n);
140+
}
141+
}, std::forward<T>(x));
135142
}
136143

137-
/**
138-
* Returns a matrix representation of the vector in column-major
139-
* order with the specified number of rows and columns.
140-
*
141-
* @param x vector of values
142-
* @param m rows
143-
* @param n columns
144-
* @return the matrix representation of the input
145-
* @throw <code>std::invalid_argument</code>
146-
* if the sizes do not match
147-
*/
148-
inline Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> to_matrix(
149-
const std::vector<int>& x, int m, int n) {
150-
static constexpr const char* function = "to_matrix(array)";
151-
int x_size = x.size();
152-
check_size_match(function, "rows * columns", m * n, "vector size", x_size);
153-
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> result(m, n);
154-
for (int i = 0; i < x_size; i++) {
155-
result.coeffRef(i) = x[i];
156-
}
157-
return result;
158-
}
159144

160145
/**
161146
* Returns a matrix representation of the vector in column-major

stan/math/prim/functor/apply_scalar_binary.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ inline auto apply_scalar_binary(F&& f, T1&& x, T2&& y) {
8585
[](auto&& f_inner, auto&& x_inner, auto&& y_inner) {
8686
using int_vec_t = promote_scalar_t<value_type_t<decltype(y_inner)>,
8787
plain_type_t<decltype(x_inner)>>;
88-
Eigen::Map<const int_vec_t> y_map(y_inner.data(), y_inner.size());
88+
auto y_map = make_holder([](auto&& y_inner_) {
89+
return Eigen::Map<const int_vec_t>(y_inner_.data(), y_inner_.size());
90+
}, std::forward<decltype(y_inner)>(y_inner));
8991
return std::forward<decltype(x_inner)>(x_inner).binaryExpr(
9092
y_map, std::forward<decltype(f_inner)>(f_inner));
9193
},
@@ -113,7 +115,9 @@ inline auto apply_scalar_binary(F&& f, T1&& x, T2&& y) {
113115
[](auto&& f_inner, auto&& x_inner, auto&& y_inner) {
114116
using int_vec_t = promote_scalar_t<value_type_t<decltype(x_inner)>,
115117
plain_type_t<decltype(y_inner)>>;
116-
Eigen::Map<const int_vec_t> x_map(x_inner.data(), x_inner.size());
118+
auto x_map = make_holder([](auto&& x_inner_) {
119+
return Eigen::Map<const int_vec_t>(x_inner_.data(), x_inner_.size());
120+
}, std::forward<decltype(x_inner)>(x_inner));
117121
return x_map.binaryExpr(std::forward<decltype(y_inner)>(y_inner),
118122
std::forward<decltype(f_inner)>(f_inner));
119123
},
@@ -263,10 +267,10 @@ template <typename F, typename T1, typename T2,
263267
require_all_std_vector_vt<is_stan_scalar, T1, T2>* = nullptr>
264268
inline auto apply_scalar_binary(F&& f, T1&& x, T2&& y) {
265269
check_matching_sizes("Binary function", "x", x, "y", y);
270+
using T_return = std::decay_t<decltype(f(x[0], y[0]))>;
266271
decltype(auto) x_vec = as_column_vector_or_scalar(std::forward<T1>(x));
267272
decltype(auto) y_vec = as_column_vector_or_scalar(std::forward<T2>(y));
268-
using T_return = std::decay_t<decltype(f(x[0], y[0]))>;
269-
std::vector<T_return> result(x.size());
273+
std::vector<T_return> result(x_vec.size());
270274
Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
271275
= x_vec.binaryExpr(y_vec, std::forward<F>(f));
272276
return result;

stan/math/prim/functor/apply_scalar_ternary.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ template <typename F, typename T1, typename T2, typename T3,
9696
inline auto apply_scalar_ternary(F&& f, T1&& x, T2&& y, T3&& z) {
9797
check_matching_sizes("Ternary function", "x", x, "y", y);
9898
check_matching_sizes("Ternary function", "y", y, "z", z);
99+
using T_return = std::decay_t<decltype(f(x[0], y[0], z[0]))>;
99100
decltype(auto) x_vec = as_column_vector_or_scalar(std::forward<T1>(x));
100101
decltype(auto) y_vec = as_column_vector_or_scalar(std::forward<T2>(y));
101102
decltype(auto) z_vec = as_column_vector_or_scalar(std::forward<T3>(z));
102-
using T_return = std::decay_t<decltype(f(x[0], y[0], z[0]))>;
103103
std::vector<T_return> result(x_vec.size());
104104
Eigen::Map<Eigen::Matrix<T_return, -1, 1>>(result.data(), result.size())
105105
= apply_scalar_ternary(std::forward<F>(f),

0 commit comments

Comments
 (0)