I'm trying to find an efficient way to compute X^T * W * X where X is a dense mat
of size e.g. 10,000 x 10 and W is a diagonal matrix (I store only the diagonal in an vec
).
For now, I use this function
arma::mat& getXtW(const arma::mat& covar,
const arma::vec& w,
arma::mat& tcovar,
size_t n, size_t K) {
size_t i, k;
for (i = 0; i < n; i++) {
for (k = 0; k < K; k++) {
tcovar(k, i) = covar(i, k) * w(i);
}
}
return tcovar;
}
and compute
tcovar = getXtW(covar, w, tcovar, n, K);
cprod = tcovar * covar;
Yet, this seems not optimal.
PS: You can see the whole code there.
Edit1: Seems I can use covar.t() * (covar.each_col() % w)
, but this doesn't seem to be much faster.
Edit2: If I implement it myself with loops in Rcpp:
arma::mat testProdW2(const arma::mat& x, const arma::vec& w) {
int n = x.n_rows;
int K = x.n_cols;
arma::mat res(K, K);
double tmp;
for (int k = 0; k < K; k++) {
for (int j = k; j < K; j++) {
tmp = 0;
for (int i = 0; i < n; i++) {
tmp += x(i, j) * w[i] * x(i, k);
}
res(j, k) = tmp;
}
}
for (int k = 0; k < K; k++) {
for (int j = 0; j < k; j++) {
res(j, k) = res(k, j);
}
}
return res;
}
This is slower than the first implementation.