私はcov(X * B)
の対角線を必要とするのでRcppEigen速い共分散
cov(X * B) = X * cov(B) * X.transpose()
私はちょうど各行X_i * B
の共分散を取得し、
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::Map;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::SparseMatrix;
using Eigen::MappedSparseMatrix;
using namespace Rcpp;
using namespace Eigen;
double foo(const Eigen::MappedSparseMatrix<double>& mm,
const Eigen::MappedSparseMatrix<double>& vcov) {
int n = mm.rows();
double out = 0;
SparseMatrix<double> mm_t = mm.adjoint();
SparseMatrix<double> var(1, 1);
var.setZero();
for (int i = 0; i < n; i++) {
var = mm.row(i) * vcov * mm_t.col(i);
out += var.coeff(0, 0);
}
return out;
}
それらを合計することができ、完全な行列の乗算を行う必要はありません。何らかの理由で、この機能は1M行では非常に遅いです。私は行単位で操作する代わりに "ブロック"を使用しようとしました。ブロックの値を操作することで、vcovによる行列乗算を高速化できると考えていました。これは関数をより速くすることはありませんでした。ここに再現可能な例があります
require(Matrix)
set.seed(100)
N = 2.5e5
p = 100
mm = rsparsematrix(N, p, .01)
vcov = rsparsematrix(p, p, .5)
system.time(foo(mm, vcov))
この機能を高速化する方法はありますか?
対角要素の合計または完全なベクトルを返しますか? – ekstroem
対角要素の合計 – JCWong