32 #ifndef MCKL_UTILITY_COVARIANCE_HPP 33 #define MCKL_UTILITY_COVARIANCE_HPP 42 template <
typename RealType =
double>
46 "**Covariance** used with RealType other than float or double");
74 bool cov_upper =
false,
bool cov_packed =
false)
84 if (mean ==
nullptr && cov ==
nullptr) {
88 internal::size_check<MCKL_BLAS_INT>(p,
"Covariance::operator()");
89 internal::size_check<MCKL_BLAS_INT>(n,
"Covariance::operator()");
93 std::accumulate(w, w + n, const_zero<result_type>());
97 std::fill(mean_.begin(), mean_.end(), 0);
98 for (std::size_t i = 0; i != n; ++i) {
99 add(p, x + i * p, mean_.data(), mean_.data());
102 for (std::size_t i = 0; i != p; ++i) {
103 mean_[i] = std::accumulate(
104 x + i * n, x + (i + 1) * n, const_zero<result_type>());
108 mean_init(layout, n, p, x, w);
110 div(p, mean_.data(), sw, mean_.data());
111 if (mean !=
nullptr) {
113 mean, mean_.data(),
sizeof(
result_type) * mean_.size());
115 if (cov ==
nullptr) {
120 w ==
nullptr ?
static_cast<result_type>(n) : swsqr(n, w);
124 std::fill(cov_.begin(), cov_.end(), 0);
125 cov_init(layout, p, static_cast<result_type *>(
nullptr));
127 cov_update(layout, n, p, x, B, BW);
131 sqrt(n, w, wsqrt_.data());
133 for (std::size_t i = 0; i != n; ++i) {
134 mul(p, x + i * p, wsqrt_[i], x_.data() + i * p);
137 for (std::size_t i = 0; i != p; ++i) {
138 mul(n, x + i * n, wsqrt_.data(), x_.data() + i * n);
141 cov_update(layout, n, p, x_.data(), B, BW);
143 cov_pack(p, cov, layout, cov_layout, cov_upper, cov_packed);
152 void mean_init(
MatrixLayout layout, std::size_t n, std::size_t p,
153 const float *x,
const float *w)
155 internal::cblas_sgemv(layout ==
RowMajor ? internal::CblasRowMajor :
156 internal::CblasColMajor,
157 internal::CblasTrans, static_cast<MCKL_BLAS_INT>(n),
158 static_cast<MCKL_BLAS_INT>(p), 1.0, x,
159 static_cast<MCKL_BLAS_INT>(layout ==
RowMajor ? p : n), w, 1, 0.0,
163 void mean_init(
MatrixLayout layout, std::size_t n, std::size_t p,
164 const double *x,
const double *w)
166 internal::cblas_dgemv(layout ==
RowMajor ? internal::CblasRowMajor :
167 internal::CblasColMajor,
168 internal::CblasTrans, static_cast<MCKL_BLAS_INT>(n),
169 static_cast<MCKL_BLAS_INT>(p), 1.0, x,
170 static_cast<MCKL_BLAS_INT>(layout ==
RowMajor ? p : n), w, 1, 0.0,
174 static float swsqr(std::size_t n,
const float *w)
176 return internal::cblas_sdot(static_cast<MCKL_BLAS_INT>(n), w, 1, w, 1);
179 static double swsqr(std::size_t n,
const double *w)
181 return internal::cblas_ddot(static_cast<MCKL_BLAS_INT>(n), w, 1, w, 1);
184 void cov_init(
MatrixLayout layout, std::size_t p,
float *)
186 internal::cblas_ssyr(layout ==
RowMajor ? internal::CblasRowMajor :
187 internal::CblasColMajor,
188 internal::CblasLower, static_cast<MCKL_BLAS_INT>(p), 1,
189 mean_.data(), 1, cov_.data(),
static_cast<MCKL_BLAS_INT>(p));
192 void cov_init(
MatrixLayout layout, std::size_t p,
double *)
194 internal::cblas_dsyr(layout ==
RowMajor ? internal::CblasRowMajor :
195 internal::CblasColMajor,
196 internal::CblasLower, static_cast<MCKL_BLAS_INT>(p), 1,
197 mean_.data(), 1, cov_.data(),
static_cast<MCKL_BLAS_INT>(p));
200 void cov_update(
MatrixLayout layout, std::size_t n, std::size_t p,
201 const float *x,
float B,
float BW)
203 internal::cblas_ssyrk(layout ==
RowMajor ? internal::CblasRowMajor :
204 internal::CblasColMajor,
205 internal::CblasLower, internal::CblasTrans,
206 static_cast<MCKL_BLAS_INT>(p), static_cast<MCKL_BLAS_INT>(n), B, x,
207 static_cast<MCKL_BLAS_INT>(layout ==
RowMajor ? p : n), -BW,
211 void cov_update(
MatrixLayout layout, std::size_t n, std::size_t p,
212 const double *x,
double B,
double BW)
214 internal::cblas_dsyrk(layout ==
RowMajor ? internal::CblasRowMajor :
215 internal::CblasColMajor,
216 internal::CblasLower, internal::CblasTrans,
217 static_cast<MCKL_BLAS_INT>(p), static_cast<MCKL_BLAS_INT>(n), B, x,
218 static_cast<MCKL_BLAS_INT>(layout ==
RowMajor ? p : n), -BW,
223 MatrixLayout cov_layout,
bool cov_upper,
bool cov_packed)
226 for (std::size_t i = 0; i != p; ++i) {
227 for (std::size_t j = 0; j != i; ++j) {
228 cov_[j * p + i] = cov_[i * p + j];
234 for (std::size_t i = 0; i != p; ++i) {
235 for (std::size_t j = 0; j != i; ++j) {
236 cov_[i * p + j] = cov_[j * p + i];
242 std::memcpy(cov, cov_.data(),
sizeof(
result_type) * cov_.size());
246 unsigned l = cov_layout ==
RowMajor ? 0 : 1;
247 unsigned u = cov_upper ? 1 : 0;
248 unsigned c = (l << 1) + u;
251 for (
size_t i = 0; i != p; ++i) {
252 for (std::size_t j = 0; j <= i; ++j) {
253 *cov++ = cov_[i * p + j];
258 for (std::size_t i = 0; i != p; ++i) {
259 for (std::size_t j = i; j != p; ++j) {
260 *cov++ = cov_[i * p + j];
265 for (std::size_t j = 0; j != p; ++j) {
266 for (std::size_t i = j; i != p; ++i) {
267 *cov++ = cov_[j * p + i];
272 for (std::size_t j = 0; j != p; ++j) {
273 for (std::size_t i = 0; i <= j; ++i) {
274 *cov++ = cov_[j * p + i];
286 #endif // MCKL_UTILITY_COVARIANCE_HPP void mul(std::size_t n, const float *a, const float *b, float *y)
std::integral_constant< bool, std::is_same< typename std::remove_cv< T >::type, float >::value||std::is_same< typename std::remove_cv< T >::type, double >::value > is_blas_floating_point
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
void sqrt(std::size_t n, const float *a, float *y)
void operator()(MatrixLayout layout, std::size_t n, std::size_t p, 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.
void div(std::size_t n, const float *a, const float *b, float *y)
MatrixLayout
Matrix layout.
void add(std::size_t n, const float *a, const float *b, float *y)