犰狳的有效距离计算

时间:2017-06-12 20:40:34

标签: c++ r rcpp armadillo

我是犰狳的新手。我有下面的代码,我认为这是低效的。有什么建议可以提高内存效率和/或速度吗?在armadillo docsRcpp gallery之后,我无法获得.colptruvec或批量插入工作。但我认为其中任何一项都会有所改进。

输入X(~100 x 30000),即使我的大型工作虚拟机也崩溃了。

Linux release 7.3.1611 (Core)
117GB RAM / 0GB SWAP
(24 x 2.494 GHz) processor(s)

R version 3.3.2 (2016-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
sp_mat arma_distmat_LT(const arma::mat& x) { // input expected X_{n x p} n << p
  int nr, nc;
  Col<double> col0, col1;

  nr = x.n_rows;
  nc = x.n_cols;

  sp_mat out(nc, nc);
  for (int i = 0; i < nc; i++) {
    col0 = x.col(i);
    for (int j = i + 1; j < nc; j++) {
      col1 = x.col(j);
      out(j, i) = as_scalar(col0.t() * col1);
    }
  }
  return out;
}

致电:sourceCpp("<file>"); dist_x <- arma_distmat_LT(X)

注意:这些是距离,因为我在计算余弦相似度,我设置了L2 norm == 1.

1 个答案:

答案 0 :(得分:1)

在我看来,好像你只是在计算(上三角)矩阵乘积t(X)%*%X。实际上,您可以使用未充分利用的crossprod函数直接在R中执行此操作。

X <- matrix(rnorm(100*30000), ncol=30000)
res <- crossprod(X, X)

我的笔记本电脑需要几分钟。如果您更改代码以使用Armadillo库,则可以使用

sp_mat arma_distmat_LT2(const arma::mat& x) { // input expected X_{n x p} n << p                               
  int nr, nc;
  Col<double> col0, col1;

  nr = x.n_rows;
  nc = x.n_cols;

  sp_mat out(nc, nc);
  out = trimatl(x.t() * x, k=-1);
  return out;
}

还需要几分钟。它使用了大量的内存,所以我怀疑你可以在内存中同时拥有很多对象。

可能会优化代码以仅计算下/上三角矩阵。

只是为了显示100 * 800矩阵的加速:

> microbenchmark(crossprod(X, X), arma_distmat_LT(X), arma_distmat_LT2(X))
Unit: milliseconds
                expr        min         lq       mean     median         uq
     crossprod(X, X)   50.25574   53.72049   57.98812   56.29532   58.71277
  arma_distmat_LT(X) 1331.83243 1471.42465 1523.74060 1492.84611 1512.45416
 arma_distmat_LT2(X)   29.69420   33.23954   36.24613   35.54700   38.05208
        max neval cld
  160.81227   100  a 
 3080.37891   100   b
   66.07351   100  a 

正如你所看到的那样,通过强制它可以获得大幅度的加速。话虽如此,我确信可以进一步优化交叉产品。