Skip to content

Commit 1841270

Browse files
authored
Merge pull request #3357 from stan-dev/fix/forward-as
Removes code that uses `forward_as`
2 parents 6f04298 + 0f8931c commit 1841270

7 files changed

Lines changed: 63 additions & 65 deletions

File tree

src/stan/model/indexing/assign.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -882,10 +882,12 @@ inline void assign(T&& x, U&& y, const char* name, const Idx1& idx1,
882882
const Idxs&... idxs) {
883883
int x_idx_size = rvalue_index_size(idx1, x.size());
884884
// If there is a reverse min_max index or negative max index
885-
if (std::is_same<std::decay_t<Idx1>, index_min_max>::value
886-
|| std::is_same<std::decay_t<Idx1>, index_max>::value) {
885+
constexpr bool is_idx1_minmax_or_max
886+
= std::is_same<std::decay_t<Idx1>, index_min_max>::value
887+
|| std::is_same<std::decay_t<Idx1>, index_max>::value;
888+
if constexpr (is_idx1_minmax_or_max) {
887889
if (x_idx_size == 0) {
888-
if (std::is_same<std::decay_t<Idx1>, index_min_max>::value) {
890+
if constexpr (std::is_same<std::decay_t<Idx1>, index_min_max>::value) {
889891
stan::math::check_size_match("array[negative_min_max, ...] assign",
890892
name, 0, "right hand side", y.size());
891893
} else {
@@ -900,7 +902,7 @@ inline void assign(T&& x, U&& y, const char* name, const Idx1& idx1,
900902
for (size_t n = 0; n < y.size(); ++n) {
901903
size_t i = rvalue_at(n, idx1);
902904
stan::math::check_range("array[multi, ...] assign", name, x.size(), i);
903-
if (std::is_rvalue_reference<U&&>::value) {
905+
if constexpr (std::is_rvalue_reference<U&&>::value) {
904906
assign(x[i - 1], std::move(y[n]), name, idxs...);
905907
} else {
906908
assign(x[i - 1], y[n], name, idxs...);

src/stan/model/indexing/assign_cl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ inline void assign(ExprLhs&& expr_lhs, const ScalRhs& scal_rhs,
291291
expr_lhs.val_op(), row_index.n_ - 1, col_index.n_ - 1, 1, 1);
292292
decltype(auto) lhs_adj = math::block_zero_based(
293293
expr_lhs.adj(), row_index.n_ - 1, col_index.n_ - 1, 1, 1);
294-
if (!is_constant<ScalRhs>::value) {
294+
if constexpr (!is_constant<ScalRhs>::value) {
295295
math::adjoint_of(scal_rhs) += math::from_matrix_cl<double>(lhs_adj);
296296
}
297297
math::results(lhs_adj, lhs_val)

src/stan/model/indexing/assign_varmat.hpp

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ inline void assign(VarVec&& x, const U& y, const char* name, index_uni idx) {
8383
x.vi_->val_.coeffRef(coeff_idx) = stan::math::value_of(y);
8484
stan::math::reverse_pass_callback([x, y, coeff_idx, prev_val]() mutable {
8585
x.vi_->val_.coeffRef(coeff_idx) = prev_val;
86-
if (!is_constant<U>::value) {
86+
if constexpr (!is_constant<U>::value) {
8787
math::adjoint_of(y) += x.adj().coeffRef(coeff_idx);
8888
}
8989
x.adj().coeffRef(coeff_idx) = 0.0;
@@ -138,7 +138,7 @@ inline void assign(Vec1&& x, const Vec2& y, const char* name,
138138
}
139139
}
140140

141-
if (!is_constant<Vec2>::value) {
141+
if constexpr (!is_constant<Vec2>::value) {
142142
stan::math::reverse_pass_callback([x, y, x_idx, prev_vals]() mutable {
143143
for (Eigen::Index i = 0; i < x_idx.size(); ++i) {
144144
if (likely(x_idx[i] != -1)) {
@@ -149,10 +149,7 @@ inline void assign(Vec1&& x, const Vec2& y, const char* name,
149149
}
150150
for (Eigen::Index i = 0; i < x_idx.size(); ++i) {
151151
if (likely(x_idx[i] != -1)) {
152-
math::forward_as<math::promote_scalar_t<math::var, Vec2>>(y)
153-
.adj()
154-
.coeffRef(i)
155-
+= prev_vals.coeff(i);
152+
y.adj().coeffRef(i) += prev_vals.coeff(i);
156153
}
157154
}
158155
});
@@ -196,7 +193,7 @@ inline void assign(Mat&& x, const U& y, const char* name, index_uni row_idx,
196193
stan::math::reverse_pass_callback(
197194
[x, y, row_idx_val, col_idx_val, prev_val]() mutable {
198195
x.vi_->val_.coeffRef(row_idx_val, col_idx_val) = prev_val;
199-
if (!is_constant<U>::value) {
196+
if constexpr (!is_constant<U>::value) {
200197
math::adjoint_of(y) += x.adj().coeff(row_idx_val, col_idx_val);
201198
}
202199
x.adj().coeffRef(row_idx_val, col_idx_val) = 0.0;
@@ -255,7 +252,7 @@ inline void assign(Mat1&& x, const Vec& y, const char* name, index_uni row_idx,
255252
x.vi_->val_.coeffRef(row_idx_val, x_idx[i]) = y_val_idx.coeff(i);
256253
}
257254
}
258-
if (!is_constant<Vec>::value) {
255+
if constexpr (!is_constant<Vec>::value) {
259256
stan::math::reverse_pass_callback(
260257
[x, y, row_idx_val, x_idx, prev_val]() mutable {
261258
for (size_t i = 0; i < x_idx.size(); ++i) {
@@ -267,10 +264,7 @@ inline void assign(Mat1&& x, const Vec& y, const char* name, index_uni row_idx,
267264
}
268265
for (size_t i = 0; i < x_idx.size(); ++i) {
269266
if (likely(x_idx[i] != -1)) {
270-
math::forward_as<math::promote_scalar_t<math::var, Vec>>(y)
271-
.adj()
272-
.coeffRef(i)
273-
+= prev_val.coeff(i);
267+
y.adj().coeffRef(i) += prev_val.coeff(i);
274268
}
275269
}
276270
});
@@ -338,7 +332,7 @@ inline void assign(Mat1&& x, const Mat2& y, const char* name,
338332
}
339333
}
340334

341-
if (!is_constant<Mat2>::value) {
335+
if constexpr (!is_constant<Mat2>::value) {
342336
stan::math::reverse_pass_callback([x, y, prev_vals, x_idx]() mutable {
343337
for (size_t i = 0; i < x_idx.size(); ++i) {
344338
if (likely(x_idx[i] != -1)) {
@@ -349,10 +343,7 @@ inline void assign(Mat1&& x, const Mat2& y, const char* name,
349343
}
350344
for (size_t i = 0; i < x_idx.size(); ++i) {
351345
if (likely(x_idx[i] != -1)) {
352-
math::forward_as<math::promote_scalar_t<math::var, Mat2>>(y)
353-
.adj()
354-
.row(i)
355-
+= prev_vals.row(i);
346+
y.adj().row(i) += prev_vals.row(i);
356347
}
357348
}
358349
});
@@ -442,7 +433,7 @@ inline void assign(Mat1&& x, const Mat2& y, const char* name,
442433
}
443434
}
444435
}
445-
if (!is_constant<Mat2>::value) {
436+
if constexpr (!is_constant<Mat2>::value) {
446437
stan::math::reverse_pass_callback(
447438
[x, y, prev_vals, x_col_idx, x_row_idx]() mutable {
448439
for (int j = 0; j < x_col_idx.size(); ++j) {
@@ -462,10 +453,7 @@ inline void assign(Mat1&& x, const Mat2& y, const char* name,
462453
if (likely(x_col_idx[j] != -1)) {
463454
for (int i = 0; i < x_row_idx.size(); ++i) {
464455
if (likely(x_row_idx[i] != -1)) {
465-
math::forward_as<math::promote_scalar_t<math::var, Mat2>>(y)
466-
.adj()
467-
.coeffRef(i, j)
468-
+= prev_vals.coeff(i, j);
456+
y.adj().coeffRef(i, j) += prev_vals.coeff(i, j);
469457
}
470458
}
471459
}

src/stan/model/indexing/rvalue.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -788,16 +788,21 @@ inline auto rvalue(StdVec&& v, const char* name, const Idx1& idx1,
788788
stan::math::check_greater_or_equal("array[..., ...] indexing", "size",
789789
index_size, 0);
790790
std::vector<inner_type> result(index_size);
791-
if ((std::is_same<std::decay_t<Idx1>, index_min_max>::value
792-
|| std::is_same<std::decay_t<Idx1>, index_max>::value)
793-
&& index_size == 0) {
794-
return result;
791+
constexpr bool is_idx1_minmax_or_max
792+
= std::is_same<std::decay_t<Idx1>, index_min_max>::value
793+
|| std::is_same<std::decay_t<Idx1>, index_max>::value;
794+
if constexpr (is_idx1_minmax_or_max) {
795+
if (index_size == 0) {
796+
return result;
797+
}
795798
}
796799
for (int i = 0; i < index_size; ++i) {
797800
const int n = rvalue_at(i, idx1);
798801
math::check_range("array[..., ...] index", name, v.size(), n);
799-
if ((!std::is_same<std::decay_t<Idx1>, index_multi>::value)
800-
&& std::is_rvalue_reference<StdVec>::value) {
802+
constexpr bool is_rvalue_multi_idx
803+
= (!std::is_same<std::decay_t<Idx1>, index_multi>::value)
804+
&& std::is_rvalue_reference<StdVec>::value;
805+
if constexpr (is_rvalue_multi_idx) {
801806
result[i] = rvalue(std::move(v[n - 1]), name, idxs...);
802807
} else {
803808
result[i] = rvalue(v[n - 1], name, idxs...);

src/stan/model/model_base.hpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -325,14 +325,16 @@ class model_base : public prob_grad {
325325
template <bool propto, bool jacobian, typename T>
326326
inline T log_prob(Eigen::Matrix<T, -1, 1>& params_r,
327327
std::ostream* msgs) const {
328-
if (propto && jacobian)
328+
if constexpr (propto && jacobian) {
329329
return log_prob_propto_jacobian(params_r, msgs);
330-
else if (propto && !jacobian)
330+
} else if constexpr (propto && !jacobian) {
331331
return log_prob_propto(params_r, msgs);
332-
else if (!propto && jacobian)
332+
} else if constexpr (!propto && jacobian) {
333333
return log_prob_jacobian(params_r, msgs);
334-
else // if (!propto && !jacobian)
334+
} else {
335+
// if (!propto && !jacobian)
335336
return log_prob(params_r, msgs);
337+
}
336338
}
337339

338340
/**
@@ -570,14 +572,15 @@ class model_base : public prob_grad {
570572
template <bool propto, bool jacobian, typename T>
571573
inline T log_prob(std::vector<T>& params_r, std::vector<int>& params_i,
572574
std::ostream* msgs) const {
573-
if (propto && jacobian)
575+
if constexpr (propto && jacobian) {
574576
return log_prob_propto_jacobian(params_r, params_i, msgs);
575-
else if (propto && !jacobian)
577+
} else if constexpr (propto && !jacobian) {
576578
return log_prob_propto(params_r, params_i, msgs);
577-
else if (!propto && jacobian)
579+
} else if constexpr (!propto && jacobian) {
578580
return log_prob_jacobian(params_r, params_i, msgs);
579-
else // if (!propto && !jacobian)
581+
} else { // if (!propto && !jacobian)
580582
return log_prob(params_r, params_i, msgs);
583+
}
581584
}
582585

583586
/**

src/test/unit/model/indexing/assign_varmat_test.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ void test_nil_vec() {
7777
EXPECT_MATRIX_EQ(x.val(), stan::math::value_of(y));
7878
stan::math::sum(x).grad();
7979
auto check_all = [](int i) { return true; };
80-
if (stan::is_var<RhsScalar>::value) {
80+
if constexpr (stan::is_var<RhsScalar>::value) {
8181
EXPECT_MATRIX_EQ(x.val(), stan::math::value_of(y));
8282
check_adjs(check_all, x, "lhs", 1);
8383
check_adjs(check_all, y, "rhs", 1);
@@ -205,14 +205,14 @@ void test_omni_vec() {
205205
EXPECT_FLOAT_EQ(y_val[3], x.val()[3]);
206206
EXPECT_FLOAT_EQ(y_val[4], x.val()[4]);
207207
sum(x).grad();
208-
if (stan::is_var<RhsScalar>::value) {
208+
if constexpr (stan::is_var<RhsScalar>::value) {
209209
EXPECT_MATRIX_EQ(x.val(), y_val);
210210
EXPECT_MATRIX_EQ(x_copy.val(), x_val);
211211
} else {
212212
EXPECT_MATRIX_EQ(x.val(), x_val);
213213
}
214214
auto check_i = [](int i) { return true; };
215-
if (stan::is_var<RhsScalar>::value) {
215+
if constexpr (stan::is_var<RhsScalar>::value) {
216216
check_adjs(check_i, x, "lhs", 1.0);
217217
} else {
218218
check_adjs(check_i, x, "lhs", 0.0);
@@ -963,15 +963,15 @@ void omni_matrix_test() {
963963
Eigen::MatrixXd x_val = x.val();
964964
auto y = conditionally_generate_linear_var_matrix<RhsScalar>(5, 5, 10);
965965
assign(x, y, "", index_omni());
966-
if (stan::is_var<RhsScalar>::value) {
966+
if constexpr (stan::is_var<RhsScalar>::value) {
967967
EXPECT_MATRIX_EQ(value_of(y), x.val());
968968
} else {
969969
EXPECT_MATRIX_EQ(value_of(y), x.val());
970970
EXPECT_MATRIX_EQ(value_of(y), x_copy.val());
971971
}
972972
sum(x).grad();
973973
auto check_all = [](int /* i */) { return true; };
974-
if (stan::is_var<RhsScalar>::value) {
974+
if constexpr (stan::is_var<RhsScalar>::value) {
975975
EXPECT_MATRIX_EQ(x.val(), value_of(y));
976976
check_adjs(check_all, check_all, x, "lhs");
977977
check_adjs(check_all, check_all, y, "rhs");
@@ -1009,15 +1009,15 @@ void omni_omni_matrix_test() {
10091009
stan::math::var lp = sum(x_copy);
10101010
lp.adj() = 1;
10111011
assign(x, y, "", index_omni(), index_omni());
1012-
if (stan::is_var<RhsScalar>::value) {
1012+
if constexpr (stan::is_var<RhsScalar>::value) {
10131013
EXPECT_MATRIX_EQ(value_of(y), x.val());
10141014
} else {
10151015
EXPECT_MATRIX_EQ(value_of(y), x.val());
10161016
EXPECT_MATRIX_EQ(value_of(y), x_copy.val());
10171017
}
10181018
sum(x).grad();
10191019
auto check_all = [](int /* i */) { return true; };
1020-
if (stan::is_var<RhsScalar>::value) {
1020+
if constexpr (stan::is_var<RhsScalar>::value) {
10211021
EXPECT_MATRIX_EQ(x.val(), value_of(y));
10221022
check_adjs(check_all, check_all, x, "lhs");
10231023
check_adjs(check_all, check_all, y, "rhs");
@@ -1494,7 +1494,7 @@ void nil_matrix() {
14941494
EXPECT_MATRIX_EQ(stan::math::value_of(y), x.val());
14951495
sum(x).grad();
14961496
auto check_all = [](int /* i */) { return true; };
1497-
if (stan::is_var<RhsScalar>::value) {
1497+
if constexpr (stan::is_var<RhsScalar>::value) {
14981498
EXPECT_MATRIX_EQ(x.val(), stan::math::value_of(y));
14991499
check_adjs(check_all, check_all, x, "lhs");
15001500
check_adjs(check_all, check_all, y, "rhs");
@@ -1550,8 +1550,8 @@ inline void assign_tester(T1&& x, const I1& idx1, const I2& idx2) {
15501550
stan::math::sum(stan::math::add(x1, x2)).grad();
15511551
// Since this just moves the pointer x1 omni is diff than
15521552
// multi
1553-
if (!std::is_same<I1, index_omni>::value
1554-
&& !std::is_same<I2, index_omni>::value) {
1553+
if constexpr (!std::is_same<I1, index_omni>::value
1554+
&& !std::is_same<I2, index_omni>::value) {
15551555
EXPECT_MATRIX_EQ(x1.val(), x2.val());
15561556
EXPECT_MATRIX_EQ(x1.adj(), x2.adj());
15571557
EXPECT_MATRIX_EQ(y.adj(),

src/test/unit/model/model_base_crtp_test.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ struct mock_model : public stan::model::model_base_crtp<mock_model> {
3636

3737
template <bool propto, bool jacobian, typename T>
3838
T log_prob(Eigen::Matrix<T, -1, 1>& params_r, std::ostream* msgs) const {
39-
if (std::is_same<T, double>::value) {
40-
if (!propto && !jacobian)
39+
if constexpr (std::is_same<T, double>::value) {
40+
if constexpr (!propto && !jacobian)
4141
return 1;
42-
else if (!propto && jacobian)
42+
else if constexpr (!propto && jacobian)
4343
return 3;
44-
else if (propto && !jacobian)
44+
else if constexpr (propto && !jacobian)
4545
return 5;
4646
else
4747
return 7;
4848
} else {
49-
if (!propto && !jacobian)
49+
if constexpr (!propto && !jacobian)
5050
return 2;
51-
else if (!propto && jacobian)
51+
else if constexpr (!propto && jacobian)
5252
return 4;
53-
else if (propto && !jacobian)
53+
else if constexpr (propto && !jacobian)
5454
return 6;
5555
else
5656
return 8;
@@ -69,21 +69,21 @@ struct mock_model : public stan::model::model_base_crtp<mock_model> {
6969
template <bool propto, bool jacobian, typename T>
7070
T log_prob(std::vector<T>& params_r, std::vector<int>& params_i,
7171
std::ostream* msgs) const {
72-
if (std::is_same<T, double>::value) {
73-
if (!propto && !jacobian)
72+
if constexpr (std::is_same<T, double>::value) {
73+
if constexpr (!propto && !jacobian)
7474
return 1;
75-
else if (!propto && jacobian)
75+
else if constexpr (!propto && jacobian)
7676
return 3;
77-
else if (propto && !jacobian)
77+
else if constexpr (propto && !jacobian)
7878
return 5;
7979
else
8080
return 7;
8181
} else {
82-
if (!propto && !jacobian)
82+
if constexpr (!propto && !jacobian)
8383
return 2;
84-
else if (!propto && jacobian)
84+
else if constexpr (!propto && jacobian)
8585
return 4;
86-
else if (propto && !jacobian)
86+
else if constexpr (propto && !jacobian)
8787
return 6;
8888
else
8989
return 8;

0 commit comments

Comments
 (0)