【发布时间】:2017-12-16 21:40:21
【问题描述】:
我已经拟合了一个回归模型,它为回归参数 B 输出协方差矩阵 S。我需要通过乘以 X 来对该协方差矩阵进行运算,然后得到新的协方差和标准错误向量
cov(X * B) = X * cov(B) * X.transpose()
因为我只需要cov(X * B)的对角线我不需要做完整的矩阵乘法,我可以得到每行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 行上非常慢。我尝试使用“块”而不是逐行对 mm 进行操作,认为通过对值块进行操作可以更快地进行与 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))
有没有办法让这个功能更快?
【问题讨论】:
-
您要返回对角线元素的总和还是完整的向量?
-
对角线元素的总和