32 #ifndef VSMC_UTILITY_COVARIANCE_HPP 33 #define VSMC_UTILITY_COVARIANCE_HPP 46 template <
typename RealType>
47 inline void cov_pack(std::size_t dim,
const RealType *cov, RealType *chol,
50 unsigned l = layout ==
RowMajor ? 0 : 1;
51 unsigned u = upper ? 1 : 0;
52 unsigned p = packed ? 1 : 0;
53 unsigned c = (l << 2) + (u << 1) + p;
56 for (std::size_t i = 0; i != dim; ++i)
57 for (std::size_t j = 0; j <= i; ++j)
58 *chol++ = cov[i * dim + j];
61 std::copy_n(cov, dim * (dim + 1) / 2, chol);
64 for (std::size_t i = 0; i != dim; ++i)
65 for (std::size_t j = 0; j <= i; ++j)
66 *chol++ = cov[j * dim + i];
69 for (std::size_t i = 0; i != dim; ++i)
70 for (std::size_t j = 0; j <= i; ++j)
71 *chol++ = cov[dim * j - j * (j + 1) / 2 + i];
74 for (std::size_t i = 0; i != dim; ++i)
75 for (std::size_t j = 0; j <= i; ++j)
76 *chol++ = cov[j * dim + i];
79 for (std::size_t i = 0; i != dim; ++i)
80 for (std::size_t j = 0; j <= i; ++j)
81 *chol++ = cov[dim * j - j * (j + 1) / 2 + i];
84 for (std::size_t j = 0; j != dim; ++j)
85 for (std::size_t i = 0; i <= j; ++i)
86 *chol++ = cov[j * dim + i];
89 std::copy_n(cov, dim * (dim + 1) / 2, chol);
95 inline int cov_chol(std::size_t dim,
float *chol)
97 return static_cast<int>(::LAPACKE_spptrf(
98 LAPACK_ROW_MAJOR,
'L', static_cast<lapack_int>(dim), chol));
103 return static_cast<int>(::LAPACKE_dpptrf(
104 LAPACK_ROW_MAJOR,
'L', static_cast<lapack_int>(dim), chol));
128 template <
typename RealType>
129 inline int cov_chol(std::size_t dim,
const RealType *cov, RealType *chol,
133 "**cov_chol** USED WITH RealType OTHER THAN float OR double");
141 template <
typename RealType =
double>
145 "**Covariance** USED WITH RealType OTHER THAN float OR double");
173 bool cov_upper =
false,
bool cov_packed =
false)
181 if (mean ==
nullptr && cov ==
nullptr)
185 MKL_INT px =
static_cast<MKL_INT
>(dim);
186 MKL_INT nx =
static_cast<MKL_INT
>(n);
187 MKL_INT xstorage = layout ==
RowMajor ? VSL_SS_MATRIX_STORAGE_COLS :
188 VSL_SS_MATRIX_STORAGE_ROWS;
189 MKL_INT cov_storage = storage(cov_layout, cov_upper, cov_packed);
190 unsigned MKL_INT64 estimates = 0;
192 estimates |= VSL_SS_MEAN;
194 estimates |= VSL_SS_COV;
197 task.
edit_cov_cor(mean, cov, &cov_storage,
nullptr,
nullptr);
198 task.
compute(estimates, VSL_SS_METHOD_FAST);
199 #else // VSMC_USE_MKL_VSL 202 std::accumulate(w, w + n, static_cast<result_type>(0));
206 std::fill(mean_.begin(), mean_.end(), 0);
207 for (std::size_t i = 0; i != n; ++i)
208 add(dim, x + i * dim, mean_.data(), mean_.data());
210 for (std::size_t i = 0; i != dim; ++i) {
211 mean_[i] = std::accumulate(x + i * n, x + (i + 1) * n,
212 static_cast<result_type>(0));
216 mean_init(layout, n, dim, x, w);
218 div(dim, mean_.data(), sw, mean_.data());
220 std::copy(mean_.begin(), mean_.end(), mean);
225 w ==
nullptr ?
static_cast<result_type>(n) : swsqr(n, w);
228 cov_.resize(dim * dim);
229 std::fill(cov_.begin(), cov_.end(), 0);
230 cov_init(layout, dim, static_cast<result_type *>(
nullptr));
232 cov_update(layout, n, dim, x, B, BW);
235 buffer_.resize(n * dim);
236 sqrt(n, w, wsqrt_.data());
238 for (std::size_t i = 0; i != n; ++i)
239 mul(dim, x + i * dim, wsqrt_[i], buffer_.data() + i * dim);
241 for (std::size_t i = 0; i != dim; ++i)
242 mul(n, x + i * n, wsqrt_.data(), buffer_.data() + i * n);
244 cov_update(layout, n, dim, buffer_.data(), B, BW);
246 cov_pack(dim, cov, layout, cov_layout, cov_upper, cov_packed);
247 #endif // VSMC_USE_MKL_VSL 252 MKL_INT storage(
MatrixLayout layout,
bool upper,
bool packed)
255 return VSL_SS_MATRIX_STORAGE_FULL;
258 return upper ? VSL_SS_MATRIX_STORAGE_U_PACKED :
259 VSL_SS_MATRIX_STORAGE_L_PACKED;
261 return upper ? VSL_SS_MATRIX_STORAGE_L_PACKED :
262 VSL_SS_MATRIX_STORAGE_U_PACKED;
264 #else // VSMC_USE_MKL_VSL 270 void mean_init(
MatrixLayout layout, std::size_t n, std::size_t dim,
271 const float *x,
const float *w)
273 ::cblas_sgemv(layout ==
RowMajor ? ::CblasRowMajor : ::CblasColMajor,
274 ::CblasTrans, static_cast<VSMC_CBLAS_INT>(n),
275 static_cast<VSMC_CBLAS_INT>(dim), 1.0, x,
276 static_cast<VSMC_CBLAS_INT>(layout ==
RowMajor ? dim : n), w, 1,
277 0.0, mean_.data(), 1);
280 void mean_init(
MatrixLayout layout, std::size_t n, std::size_t dim,
281 const double *x,
const double *w)
283 ::cblas_dgemv(layout ==
RowMajor ? ::CblasRowMajor : ::CblasColMajor,
284 ::CblasTrans, static_cast<VSMC_CBLAS_INT>(n),
285 static_cast<VSMC_CBLAS_INT>(dim), 1.0, x,
286 static_cast<VSMC_CBLAS_INT>(layout ==
RowMajor ? dim : n), w, 1,
287 0.0, mean_.data(), 1);
290 static float swsqr(std::size_t n,
const float *w)
292 return ::cblas_sdot(static_cast<VSMC_CBLAS_INT>(n), w, 1, w, 1);
295 static double swsqr(std::size_t n,
const double *w)
297 return ::cblas_ddot(static_cast<VSMC_CBLAS_INT>(n), w, 1, w, 1);
300 void cov_init(
MatrixLayout layout, std::size_t dim,
float *)
302 ::cblas_ssyr(layout ==
RowMajor ? ::CblasRowMajor : ::CblasColMajor,
303 ::CblasLower, static_cast<VSMC_CBLAS_INT>(dim), 1, mean_.data(), 1,
307 void cov_init(
MatrixLayout layout, std::size_t dim,
double *)
309 ::cblas_dsyr(layout ==
RowMajor ? ::CblasRowMajor : ::CblasColMajor,
310 ::CblasLower, static_cast<VSMC_CBLAS_INT>(dim), 1, mean_.data(), 1,
314 void cov_update(
MatrixLayout layout, std::size_t n, std::size_t dim,
315 const float *x,
float B,
float BW)
317 ::cblas_ssyrk(layout ==
RowMajor ? ::CblasRowMajor : ::CblasColMajor,
318 ::CblasLower, ::CblasTrans, static_cast<VSMC_CBLAS_INT>(dim),
319 static_cast<VSMC_CBLAS_INT>(n), B, x,
320 static_cast<VSMC_CBLAS_INT>(layout ==
RowMajor ? dim : n), -BW,
324 void cov_update(
MatrixLayout layout, std::size_t n, std::size_t dim,
325 const double *x,
double B,
double BW)
327 ::cblas_dsyrk(layout ==
RowMajor ? ::CblasRowMajor : ::CblasColMajor,
328 ::CblasLower, ::CblasTrans, static_cast<VSMC_CBLAS_INT>(dim),
329 static_cast<VSMC_CBLAS_INT>(n), B, x,
330 static_cast<VSMC_CBLAS_INT>(layout ==
RowMajor ? dim : n), -BW,
335 MatrixLayout cov_layout,
bool cov_upper,
bool cov_packed)
338 for (std::size_t i = 0; i != dim; ++i)
339 for (std::size_t j = 0; j != i; ++j)
340 cov_[j * dim + i] = cov_[i * dim + j];
343 for (std::size_t i = 0; i != dim; ++i)
344 for (std::size_t j = 0; j != i; ++j)
345 cov_[i * dim + j] = cov_[j * dim + i];
348 std::copy(cov_.begin(), cov_.end(), cov);
352 unsigned l = cov_layout ==
RowMajor ? 0 : 1;
353 unsigned u = cov_upper ? 1 : 0;
354 unsigned c = (l << 1) + u;
357 for (
size_t i = 0; i != dim; ++i)
358 for (std::size_t j = 0; j <= i; ++j)
359 *cov++ = cov_[i * dim + j];
362 for (std::size_t i = 0; i != dim; ++i)
363 for (std::size_t j = i; j != dim; ++j)
364 *cov++ = cov_[i * dim + j];
367 for (std::size_t j = 0; j != dim; ++j)
368 for (std::size_t i = j; i != dim; ++i)
369 *cov++ = cov_[j * dim + i];
372 for (std::size_t j = 0; j != dim; ++j)
373 for (std::size_t i = 0; i <= j; ++i)
374 *cov++ = cov_[j * dim + i];
379 #endif // VSMC_USE_MKL_VSL 384 #endif // VSMC_UTILITY_COVARIANCE_HPP
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
void mul(std::size_t n, const float *a, const float *b, float *y)
void sqrt(std::size_t n, const float *a, float *y)
MatrixLayout
Matrix layout.
int compute(unsigned MKL_INT64 estimates, MKL_INT method)
vslSSCompute
void operator()(MatrixLayout layout, std::size_t n, std::size_t dim, const result_type *x, const result_type *w, result_type *mean, result_type *cov, MatrixLayout cov_layout=RowMajor, bool cov_upper=false, bool cov_packed=false)
Compute the sample covariance matrix.
int cov_chol(std::size_t dim, float *chol)
int edit_cov_cor(const result_type *mean, const result_type *cov, const MKL_INT *cov_storage, const result_type *cor, const MKL_INT *cor_storage)
vslSSEditCovCor
void div(std::size_t n, const float *a, const float *b, float *y)
void cov_pack(std::size_t dim, const RealType *cov, RealType *chol, MatrixLayout layout, bool upper, bool packed)
void add(std::size_t n, const float *a, const float *b, float *y)