32 #ifndef VSMC_UTILITY_COVARIANCE_HPP 33 #define VSMC_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)
82 if (mean ==
nullptr && cov ==
nullptr)
85 internal::size_check<VSMC_BLAS_INT>(p,
"Covariance::operator()");
86 internal::size_check<VSMC_BLAS_INT>(n,
"Covariance::operator()");
90 std::accumulate(w, w + n, static_cast<result_type>(0));
94 std::fill(mean_.begin(), mean_.end(), 0);
95 for (std::size_t i = 0; i != n; ++i)
96 add(p, x + i * p, mean_.data(), mean_.data());
98 for (std::size_t i = 0; i != p; ++i) {
99 mean_[i] = std::accumulate(x + i * n, x + (i + 1) * n,
100 static_cast<result_type>(0));
104 mean_init(layout, n, p, x, w);
106 div(p, mean_.data(), sw, mean_.data());
108 std::copy(mean_.begin(), mean_.end(), mean);
113 w ==
nullptr ?
static_cast<result_type>(n) : swsqr(n, w);
117 std::fill(cov_.begin(), cov_.end(), 0);
118 cov_init(layout, p, static_cast<result_type *>(
nullptr));
120 cov_update(layout, n, p, x, B, BW);
123 buffer_.resize(n * p);
124 sqrt(n, w, wsqrt_.data());
126 for (std::size_t i = 0; i != n; ++i)
127 mul(p, x + i * p, wsqrt_[i], buffer_.data() + i * p);
129 for (std::size_t i = 0; i != p; ++i)
130 mul(n, x + i * n, wsqrt_.data(), buffer_.data() + i * n);
132 cov_update(layout, n, p, buffer_.data(), B, BW);
134 cov_pack(p, cov, layout, cov_layout, cov_upper, cov_packed);
143 void mean_init(
MatrixLayout layout, std::size_t n, std::size_t p,
144 const float *x,
const float *w)
146 internal::cblas_sgemv(layout ==
RowMajor ? internal::CblasRowMajor :
147 internal::CblasColMajor,
148 internal::CblasTrans, static_cast<VSMC_BLAS_INT>(n),
149 static_cast<VSMC_BLAS_INT>(p), 1.0, x,
150 static_cast<VSMC_BLAS_INT>(layout ==
RowMajor ? p : n), w, 1, 0.0,
154 void mean_init(
MatrixLayout layout, std::size_t n, std::size_t p,
155 const double *x,
const double *w)
157 internal::cblas_dgemv(layout ==
RowMajor ? internal::CblasRowMajor :
158 internal::CblasColMajor,
159 internal::CblasTrans, static_cast<VSMC_BLAS_INT>(n),
160 static_cast<VSMC_BLAS_INT>(p), 1.0, x,
161 static_cast<VSMC_BLAS_INT>(layout ==
RowMajor ? p : n), w, 1, 0.0,
165 static float swsqr(std::size_t n,
const float *w)
167 return internal::cblas_sdot(static_cast<VSMC_BLAS_INT>(n), w, 1, w, 1);
170 static double swsqr(std::size_t n,
const double *w)
172 return internal::cblas_ddot(static_cast<VSMC_BLAS_INT>(n), w, 1, w, 1);
175 void cov_init(
MatrixLayout layout, std::size_t p,
float *)
177 internal::cblas_ssyr(layout ==
RowMajor ? internal::CblasRowMajor :
178 internal::CblasColMajor,
179 internal::CblasLower, static_cast<VSMC_BLAS_INT>(p), 1,
180 mean_.data(), 1, cov_.data(),
static_cast<VSMC_BLAS_INT>(p));
183 void cov_init(
MatrixLayout layout, std::size_t p,
double *)
185 internal::cblas_dsyr(layout ==
RowMajor ? internal::CblasRowMajor :
186 internal::CblasColMajor,
187 internal::CblasLower, static_cast<VSMC_BLAS_INT>(p), 1,
188 mean_.data(), 1, cov_.data(),
static_cast<VSMC_BLAS_INT>(p));
191 void cov_update(
MatrixLayout layout, std::size_t n, std::size_t p,
192 const float *x,
float B,
float BW)
194 internal::cblas_ssyrk(layout ==
RowMajor ? internal::CblasRowMajor :
195 internal::CblasColMajor,
196 internal::CblasLower, internal::CblasTrans,
197 static_cast<VSMC_BLAS_INT>(p), static_cast<VSMC_BLAS_INT>(n), B, x,
198 static_cast<VSMC_BLAS_INT>(layout ==
RowMajor ? p : n), -BW,
202 void cov_update(
MatrixLayout layout, std::size_t n, std::size_t p,
203 const double *x,
double B,
double BW)
205 internal::cblas_dsyrk(layout ==
RowMajor ? internal::CblasRowMajor :
206 internal::CblasColMajor,
207 internal::CblasLower, internal::CblasTrans,
208 static_cast<VSMC_BLAS_INT>(p), static_cast<VSMC_BLAS_INT>(n), B, x,
209 static_cast<VSMC_BLAS_INT>(layout ==
RowMajor ? p : n), -BW,
214 MatrixLayout cov_layout,
bool cov_upper,
bool cov_packed)
217 for (std::size_t i = 0; i != p; ++i)
218 for (std::size_t j = 0; j != i; ++j)
219 cov_[j * p + i] = cov_[i * p + j];
222 for (std::size_t i = 0; i != p; ++i)
223 for (std::size_t j = 0; j != i; ++j)
224 cov_[i * p + j] = cov_[j * p + i];
227 std::copy(cov_.begin(), cov_.end(), cov);
231 unsigned l = cov_layout ==
RowMajor ? 0 : 1;
232 unsigned u = cov_upper ? 1 : 0;
233 unsigned c = (l << 1) + u;
236 for (
size_t i = 0; i != p; ++i)
237 for (std::size_t j = 0; j <= i; ++j)
238 *cov++ = cov_[i * p + j];
241 for (std::size_t i = 0; i != p; ++i)
242 for (std::size_t j = i; j != p; ++j)
243 *cov++ = cov_[i * p + j];
246 for (std::size_t j = 0; j != p; ++j)
247 for (std::size_t i = j; i != p; ++i)
248 *cov++ = cov_[j * p + i];
251 for (std::size_t j = 0; j != p; ++j)
252 for (std::size_t i = 0; i <= j; ++i)
253 *cov++ = cov_[j * p + i];
262 #endif // VSMC_UTILITY_COVARIANCE_HPP std::vector< T, Alloc > Vector
std::vector with Allocator as default allocator
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.
void div(std::size_t n, const float *a, const float *b, float *y)
void add(std::size_t n, const float *a, const float *b, 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.