Skip to content

Commit e62c148

Browse files
committed
Merge commit 'f1905f68276b9cc578bb1c7ab3f8e42266e0074a' into HEAD
2 parents e917df0 + f1905f6 commit e62c148

16 files changed

Lines changed: 808 additions & 767 deletions

benchmarks/benchmark.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ def benchmark(
351351
if "matrix" in arg:
352352
arg_dimm = 2
353353
if "[" in arg:
354-
arg_dimm += len(arg.split("[")[1])
354+
arg_dimm += len(arg.split("]")[0].split("[")[1])
355355
if arg_dimm == dimm:
356356
args_with_max_dimm += 1
357357
elif arg_dimm > dimm:
@@ -480,11 +480,12 @@ def benchmark(
480480
code += "stan::math::to_var_value({}), ".format(var_name)
481481
else:
482482
code += var_name + ", "
483-
if opencl == "base":
484-
var_conversions += " stan::math::opencl_context.queue().finish();\n"
485483
code = code[:-2] + "));\n"
486484
if "Rev" in arg_overloads:
487485
code += " stan::math::grad();\n"
486+
if opencl == "base":
487+
code += " stan::math::opencl_context.queue().finish();\n"
488+
var_conversions += " stan::math::opencl_context.queue().finish();\n"
488489
result += BENCHMARK_TEMPLATE.format(
489490
benchmark_name=benchmark_name,
490491
setup=setup,

stan/math/prim/fun.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@
264264
#include <stan/math/prim/fun/quad_form.hpp>
265265
#include <stan/math/prim/fun/quad_form_diag.hpp>
266266
#include <stan/math/prim/fun/quad_form_sym.hpp>
267+
#include <stan/math/prim/fun/quantile.hpp>
267268
#include <stan/math/prim/fun/rank.hpp>
268269
#include <stan/math/prim/fun/read_corr_L.hpp>
269270
#include <stan/math/prim/fun/read_corr_matrix.hpp>

stan/math/prim/fun/csr_matrix_times_vector.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ namespace math {
6969
* for a given sparse matrix.
7070
* @throw std::out_of_range if any of the indexes are out of range.
7171
*/
72-
template <typename T1, typename T2>
72+
template <typename T1, typename T2,
73+
require_not_t<conjunction<std::is_arithmetic<scalar_type_t<T1>>,
74+
is_var<scalar_type_t<T2>>>>* = nullptr>
7375
inline Eigen::Matrix<return_type_t<T1, T2>, Eigen::Dynamic, 1>
7476
csr_matrix_times_vector(int m, int n, const T1& w, const std::vector<int>& v,
7577
const std::vector<int>& u, const T2& b) {

stan/math/prim/fun/gp_dot_prod_cov.hpp

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,22 @@ gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x, Eigen::Dynamic, 1>> &x,
5454
}
5555

5656
T_sigma sigma_sq = square(sigma);
57-
58-
for (size_t i = 0; i < (x_size - 1); ++i) {
59-
cov(i, i) = sigma_sq + dot_self(x[i]);
60-
for (size_t j = i + 1; j < x_size; ++j) {
61-
cov(i, j) = sigma_sq + dot_product(x[i], x[j]);
62-
cov(j, i) = cov(i, j);
57+
size_t block_size = 10;
58+
59+
for (size_t jb = 0; jb < x_size; jb += block_size) {
60+
for (size_t ib = jb; ib < x_size; ib += block_size) {
61+
size_t j_end = std::min(x_size, jb + block_size);
62+
for (size_t j = jb; j < j_end; ++j) {
63+
cov.coeffRef(j, j) = sigma_sq + dot_self(x[j]);
64+
size_t i_end = std::min(x_size, ib + block_size);
65+
for (size_t i = std::max(ib, j + 1); i < i_end; ++i) {
66+
cov.coeffRef(j, i) = cov.coeffRef(i, j)
67+
= sigma_sq + dot_product(x[i], x[j]);
68+
}
69+
}
6370
}
6471
}
65-
cov(x_size - 1, x_size - 1) = sigma_sq + dot_self(x[x_size - 1]);
72+
cov.coeffRef(x_size - 1, x_size - 1) = sigma_sq + dot_self(x[x_size - 1]);
6673
return cov;
6774
}
6875

@@ -91,12 +98,10 @@ gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x, Eigen::Dynamic, 1>> &x,
9198
template <typename T_x, typename T_sigma>
9299
Eigen::Matrix<return_type_t<T_x, T_sigma>, Eigen::Dynamic, Eigen::Dynamic>
93100
gp_dot_prod_cov(const std::vector<T_x> &x, const T_sigma &sigma) {
94-
check_not_nan("gp_dot_prod_cov", "sigma", sigma);
95101
check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
96102
check_finite("gp_dot_prod_cov", "sigma", sigma);
97103

98104
size_t x_size = x.size();
99-
check_not_nan("gp_dot_prod_cov", "x", x);
100105
check_finite("gp_dot_prod_cov", "x", x);
101106

102107
Eigen::Matrix<return_type_t<T_x, T_sigma>, Eigen::Dynamic, Eigen::Dynamic>
@@ -106,12 +111,18 @@ gp_dot_prod_cov(const std::vector<T_x> &x, const T_sigma &sigma) {
106111
}
107112

108113
T_sigma sigma_sq = square(sigma);
109-
110-
for (size_t i = 0; i < (x_size - 1); ++i) {
111-
cov(i, i) = sigma_sq + x[i] * x[i];
112-
for (size_t j = i + 1; j < x_size; ++j) {
113-
cov(i, j) = sigma_sq + x[i] * x[j];
114-
cov(j, i) = cov(i, j);
114+
size_t block_size = 10;
115+
116+
for (size_t jb = 0; jb < x_size; jb += block_size) {
117+
for (size_t ib = jb; ib < x_size; ib += block_size) {
118+
size_t j_end = std::min(x_size, jb + block_size);
119+
for (size_t j = jb; j < j_end; ++j) {
120+
cov.coeffRef(j, j) = sigma_sq + x[j] * x[j];
121+
size_t i_end = std::min(x_size, ib + block_size);
122+
for (size_t i = std::max(ib, j + 1); i < i_end; ++i) {
123+
cov.coeffRef(j, i) = cov.coeffRef(i, j) = sigma_sq + x[i] * x[j];
124+
}
125+
}
115126
}
116127
}
117128
cov(x_size - 1, x_size - 1) = sigma_sq + x[x_size - 1] * x[x_size - 1];
@@ -146,18 +157,15 @@ Eigen::Matrix<return_type_t<T_x1, T_x2, T_sigma>, Eigen::Dynamic,
146157
gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x1, Eigen::Dynamic, 1>> &x1,
147158
const std::vector<Eigen::Matrix<T_x2, Eigen::Dynamic, 1>> &x2,
148159
const T_sigma &sigma) {
149-
check_not_nan("gp_dot_prod_cov", "sigma", sigma);
150160
check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
151161
check_finite("gp_dot_prod_cov", "sigma", sigma);
152162

153163
size_t x1_size = x1.size();
154164
size_t x2_size = x2.size();
155165
for (size_t i = 0; i < x1_size; ++i) {
156-
check_not_nan("gp_dot_prod_cov", "x1", x1[i]);
157166
check_finite("gp_dot_prod_cov", "x1", x1[i]);
158167
}
159168
for (size_t i = 0; i < x2_size; ++i) {
160-
check_not_nan("gp_dot_prod_cov", "x2", x2[i]);
161169
check_finite("gp_dot_prod_cov", "x2", x2[i]);
162170
}
163171
Eigen::Matrix<return_type_t<T_x1, T_x2, T_sigma>, Eigen::Dynamic,
@@ -169,10 +177,17 @@ gp_dot_prod_cov(const std::vector<Eigen::Matrix<T_x1, Eigen::Dynamic, 1>> &x1,
169177
}
170178

171179
T_sigma sigma_sq = square(sigma);
172-
173-
for (size_t i = 0; i < x1_size; ++i) {
174-
for (size_t j = 0; j < x2_size; ++j) {
175-
cov(i, j) = sigma_sq + dot_product(x1[i], x2[j]);
180+
size_t block_size = 10;
181+
182+
for (size_t ib = 0; ib < x1_size; ib += block_size) {
183+
for (size_t jb = 0; jb < x2_size; jb += block_size) {
184+
size_t j_end = std::min(x2_size, jb + block_size);
185+
for (size_t j = jb; j < j_end; ++j) {
186+
size_t i_end = std::min(x1_size, ib + block_size);
187+
for (size_t i = ib; i < i_end; ++i) {
188+
cov(i, j) = sigma_sq + dot_product(x1[i], x2[j]);
189+
}
190+
}
176191
}
177192
}
178193
return cov;
@@ -205,15 +220,12 @@ Eigen::Matrix<return_type_t<T_x1, T_x2, T_sigma>, Eigen::Dynamic,
205220
Eigen::Dynamic>
206221
gp_dot_prod_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
207222
const T_sigma &sigma) {
208-
check_not_nan("gp_dot_prod_cov", "sigma", sigma);
209223
check_nonnegative("gp_dot_prod_cov", "sigma", sigma);
210224
check_finite("gp_dot_prod_cov", "sigma", sigma);
211225

212226
size_t x1_size = x1.size();
213227
size_t x2_size = x2.size();
214-
check_not_nan("gp_dot_prod_cov", "x1", x1);
215228
check_finite("gp_dot_prod_cov", "x1", x1);
216-
check_not_nan("gp_dot_prod_cov", "x2", x2);
217229
check_finite("gp_dot_prod_cov", "x2", x2);
218230

219231
Eigen::Matrix<return_type_t<T_x1, T_x2, T_sigma>, Eigen::Dynamic,

stan/math/prim/fun/gp_exp_quad_cov.hpp

Lines changed: 26 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -41,40 +41,18 @@ gp_exp_quad_cov(const std::vector<T_x> &x, const T_sigma &sigma_sq,
4141
Eigen::Dynamic>
4242
cov(x_size, x_size);
4343
cov.diagonal().array() = sigma_sq;
44-
for (size_t j = 0; j < x_size; ++j) {
45-
for (size_t i = j + 1; i < x_size; ++i) {
46-
cov(i, j)
47-
= sigma_sq * exp(squared_distance(x[i], x[j]) * neg_half_inv_l_sq);
48-
}
49-
}
50-
cov.template triangularView<Eigen::Upper>() = cov.transpose();
51-
return cov;
52-
}
53-
54-
/**
55-
* Returns a squared exponential kernel.
56-
*
57-
* @tparam T_x type for each scalar
58-
* @tparam T_sigma type of parameter sigma
59-
*
60-
* @param x std::vector of Eigen vectors of scalars.
61-
* @param sigma_sq square root of the marginal standard deviation or magnitude
62-
* @return squared distance
63-
* x is nan or infinite
64-
*/
65-
template <typename T_x, typename T_sigma>
66-
inline typename Eigen::Matrix<return_type_t<T_x, T_sigma>, Eigen::Dynamic,
67-
Eigen::Dynamic>
68-
gp_exp_quad_cov(const std::vector<Eigen::Matrix<T_x, -1, 1>> &x,
69-
const T_sigma &sigma_sq) {
70-
using std::exp;
71-
const auto x_size = x.size();
72-
Eigen::Matrix<return_type_t<T_x, T_sigma>, Eigen::Dynamic, Eigen::Dynamic>
73-
cov(x_size, x_size);
74-
cov.diagonal().array() = sigma_sq;
75-
for (size_t j = 0; j < x_size; ++j) {
76-
for (size_t i = j + 1; i < x_size; ++i) {
77-
cov(i, j) = sigma_sq * exp(-0.5 * (x[i] - x[j]).squaredNorm());
44+
size_t block_size = 10;
45+
for (size_t jb = 0; jb < x.size(); jb += block_size) {
46+
for (size_t ib = jb; ib < x.size(); ib += block_size) {
47+
size_t j_end = std::min(x_size, jb + block_size);
48+
for (size_t j = jb; j < j_end; ++j) {
49+
size_t i_end = std::min(x_size, ib + block_size);
50+
for (size_t i = std::max(ib, j + 1); i < i_end; ++i) {
51+
cov.coeffRef(i, j)
52+
= sigma_sq
53+
* exp(squared_distance(x[i], x[j]) * neg_half_inv_l_sq);
54+
}
55+
}
7856
}
7957
}
8058
cov.template triangularView<Eigen::Upper>() = cov.transpose();
@@ -108,42 +86,19 @@ gp_exp_quad_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
10886
Eigen::Matrix<return_type_t<T_x1, T_x2, T_sigma, T_l>, Eigen::Dynamic,
10987
Eigen::Dynamic>
11088
cov(x1.size(), x2.size());
111-
for (size_t i = 0; i < x1.size(); ++i) {
112-
for (size_t j = 0; j < x2.size(); ++j) {
113-
cov(i, j)
114-
= sigma_sq * exp(squared_distance(x1[i], x2[j]) * neg_half_inv_l_sq);
115-
}
116-
}
117-
return cov;
118-
}
89+
size_t block_size = 10;
11990

120-
/**
121-
* Returns a squared exponential kernel.
122-
*
123-
* This function is for the cross covariance
124-
* matrix needed to compute the posterior predictive density.
125-
*
126-
* @tparam T_x1 type of first std::vector of elements
127-
* @tparam T_x2 type of second std::vector of elements
128-
* @tparam T_s type of sigma
129-
*
130-
* @param x1 std::vector of Eigen vectors of scalars.
131-
* @param x2 std::vector of Eigen vectors of scalars.
132-
* @param sigma_sq square root of the marginal standard deviation or magnitude
133-
* @return squared distance
134-
*/
135-
template <typename T_x1, typename T_x2, typename T_s>
136-
inline typename Eigen::Matrix<return_type_t<T_x1, T_x2, T_s>, Eigen::Dynamic,
137-
Eigen::Dynamic>
138-
gp_exp_quad_cov(const std::vector<Eigen::Matrix<T_x1, -1, 1>> &x1,
139-
const std::vector<Eigen::Matrix<T_x2, -1, 1>> &x2,
140-
const T_s &sigma_sq) {
141-
using std::exp;
142-
Eigen::Matrix<return_type_t<T_x1, T_x2, T_s>, Eigen::Dynamic, Eigen::Dynamic>
143-
cov(x1.size(), x2.size());
144-
for (size_t i = 0; i < x1.size(); ++i) {
145-
for (size_t j = 0; j < x2.size(); ++j) {
146-
cov(i, j) = sigma_sq * exp(-0.5 * (x1[i] - x2[j]).squaredNorm());
91+
for (size_t ib = 0; ib < x1.size(); ib += block_size) {
92+
for (size_t jb = 0; jb < x2.size(); jb += block_size) {
93+
size_t j_end = std::min(x2.size(), jb + block_size);
94+
for (size_t j = jb; j < j_end; ++j) {
95+
size_t i_end = std::min(x1.size(), ib + block_size);
96+
for (size_t i = ib; i < i_end; ++i) {
97+
cov.coeffRef(i, j)
98+
= sigma_sq
99+
* exp(squared_distance(x1[i], x2[j]) * neg_half_inv_l_sq);
100+
}
101+
}
147102
}
148103
}
149104
return cov;
@@ -224,7 +179,7 @@ gp_exp_quad_cov(const std::vector<Eigen::Matrix<T_x, -1, 1>> &x,
224179
check_size_match("gp_exp_quad_cov", "x dimension", x[0].size(),
225180
"number of length scales", length_scale.size());
226181
cov = internal::gp_exp_quad_cov(divide_columns(x, length_scale),
227-
square(sigma));
182+
square(sigma), -0.5);
228183
return cov;
229184
}
230185

@@ -330,7 +285,7 @@ gp_exp_quad_cov(const std::vector<Eigen::Matrix<T_x1, -1, 1>> &x1,
330285
"number of length scales", l_size);
331286
cov = internal::gp_exp_quad_cov(divide_columns(x1, length_scale),
332287
divide_columns(x2, length_scale),
333-
square(sigma));
288+
square(sigma), -0.5);
334289
return cov;
335290
}
336291

stan/math/prim/fun/gp_exponential_cov.hpp

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,18 @@ gp_exponential_cov(const std::vector<T_x> &x, const T_s &sigma,
6464
T_s sigma_sq = square(sigma);
6565
T_l neg_inv_l = -1.0 / length_scale;
6666

67-
for (size_t i = 0; i < x_size; ++i) {
68-
cov(i, i) = sigma_sq;
69-
for (size_t j = i + 1; j < x_size; ++j) {
70-
cov(i, j) = sigma_sq * exp(neg_inv_l * distance(x[i], x[j]));
71-
cov(j, i) = cov(i, j);
67+
size_t block_size = 10;
68+
for (size_t jb = 0; jb < x_size; jb += block_size) {
69+
for (size_t ib = jb; ib < x_size; ib += block_size) {
70+
size_t j_end = std::min(x_size, jb + block_size);
71+
for (size_t j = jb; j < j_end; ++j) {
72+
cov(j, j) = sigma_sq;
73+
size_t i_end = std::min(x_size, ib + block_size);
74+
for (size_t i = std::max(ib, j + 1); i < i_end; ++i) {
75+
cov.coeffRef(j, i) = cov.coeffRef(i, j)
76+
= sigma_sq * exp(neg_inv_l * distance(x[i], x[j]));
77+
}
78+
}
7279
}
7380
}
7481
return cov;
@@ -121,12 +128,18 @@ gp_exponential_cov(const std::vector<Eigen::Matrix<T_x, -1, 1>> &x,
121128
= divide_columns(x, length_scale);
122129

123130
T_s sigma_sq = square(sigma);
124-
for (size_t i = 0; i < x_size; ++i) {
125-
cov(i, i) = sigma_sq;
126-
for (size_t j = i + 1; j < x_size; ++j) {
127-
return_type_t<T_x, T_l> dist = distance(x_new[i], x_new[j]);
128-
cov(i, j) = sigma_sq * exp(-dist);
129-
cov(j, i) = cov(i, j);
131+
size_t block_size = 10;
132+
for (size_t jb = 0; jb < x_size; jb += block_size) {
133+
for (size_t ib = jb; ib < x_size; ib += block_size) {
134+
size_t j_end = std::min(x_size, jb + block_size);
135+
for (size_t j = jb; j < j_end; ++j) {
136+
cov(j, j) = sigma_sq;
137+
size_t i_end = std::min(x_size, ib + block_size);
138+
for (size_t i = std::max(ib, j + 1); i < i_end; ++i) {
139+
return_type_t<T_x, T_l> dist = distance(x_new[i], x_new[j]);
140+
cov.coeffRef(j, i) = cov.coeffRef(i, j) = sigma_sq * exp(-dist);
141+
}
142+
}
130143
}
131144
}
132145
return cov;
@@ -192,9 +205,17 @@ gp_exponential_cov(const std::vector<T_x1> &x1, const std::vector<T_x2> &x2,
192205

193206
T_s sigma_sq = square(sigma);
194207
T_l neg_inv_l = -1.0 / length_scale;
195-
for (size_t i = 0; i < x1_size; ++i) {
196-
for (size_t j = 0; j < x2_size; ++j) {
197-
cov(i, j) = sigma_sq * exp(neg_inv_l * distance(x1[i], x2[j]));
208+
size_t block_size = 10;
209+
210+
for (size_t ib = 0; ib < x1_size; ib += block_size) {
211+
for (size_t jb = 0; jb < x2_size; jb += block_size) {
212+
size_t j_end = std::min(x2_size, jb + block_size);
213+
for (size_t j = jb; j < j_end; ++j) {
214+
size_t i_end = std::min(x1_size, ib + block_size);
215+
for (size_t i = ib; i < i_end; ++i) {
216+
cov(i, j) = sigma_sq * exp(neg_inv_l * distance(x1[i], x2[j]));
217+
}
218+
}
198219
}
199220
}
200221
return cov;
@@ -268,9 +289,17 @@ gp_exponential_cov(const std::vector<Eigen::Matrix<T_x1, -1, 1>> &x1,
268289
std::vector<Eigen::Matrix<return_type_t<T_x2, T_l>, -1, 1>> x2_new
269290
= divide_columns(x2, length_scale);
270291

271-
for (size_t i = 0; i < x1_size; ++i) {
272-
for (size_t j = 0; j < x2_size; ++j) {
273-
cov(i, j) = sigma_sq * exp(-distance(x1_new[i], x2_new[j]));
292+
size_t block_size = 10;
293+
294+
for (size_t ib = 0; ib < x1_size; ib += block_size) {
295+
for (size_t jb = 0; jb < x2_size; jb += block_size) {
296+
size_t j_end = std::min(x2_size, jb + block_size);
297+
for (size_t j = jb; j < j_end; ++j) {
298+
size_t i_end = std::min(x1_size, ib + block_size);
299+
for (size_t i = ib; i < i_end; ++i) {
300+
cov(i, j) = sigma_sq * exp(-distance(x1_new[i], x2_new[j]));
301+
}
302+
}
274303
}
275304
}
276305
return cov;

0 commit comments

Comments
 (0)