RcppEigen LLT得到了NaN载体

时间:2018-08-14 02:16:24

标签: eigen rcpp

我正在尝试使用下面的RcppEigen函数来求解线性模型。它编译没有错误,但是当我在R中应用它时,它给出了NaN值的向量。我在不带R的C ++上尝试了类似的脚本,并且效果很好。有什么建议吗?

// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::plugins("cpp11")]]
#include <RcppEigen.h>
#include <Rcpp.h>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;
using namespace Rcpp;

// [[Rcpp::export]]
SEXP LLtSolve(const MatrixXd A, const MatrixXd b) {
    LLT<MatrixXd> llt;
    llt.compute(A);
    return Rcpp::wrap(llt.solve(b));
}

R代码示例:

library(Rcpp)
sourceCpp("Functions.cpp") # contains the previous LLtSolve function
n=1000
A=matrix(rnorm(n*n),nrow=n,ncol=n)
b=matrix(rnorm(n),nrow=n,ncol=1)
xxx=Sys.time()
f=LLtSolve(A,b)
Sys.time()-xxx
f[1:4]

1 个答案:

答案 0 :(得分:1)

如果减少n,您的代码将起作用。例如:

> set.seed(42)

> n=500

> A=matrix(rnorm(n*n),nrow=n,ncol=n)

> b=matrix(rnorm(n),nrow=n,ncol=1)

> f=LLtSolve(A,b)

> min(f)
[1] -1.40086e+300

> max(f)
[1] 1.757129e+300

但是,最小值和最大值已经非常极端。当您进一步增加问题的大小时,您将到达结果不再可表示为double的地步:

> .Machine$double.xmax
[1] 1.797693e+308
> .Machine$double.xmin
[1] 2.225074e-308

sparse matrix并非如此,例如:

// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
#include <Eigen/SparseLU>

using namespace Eigen;

// [[Rcpp::export]]
MatrixXd SparseSolve(const SparseMatrix<double>& A, const MatrixXd& b) {
  SparseLU<SparseMatrix<double> > solver;
  solver.compute(A);
  if(solver.info()!=Success) {
    Rcpp::stop("decomposition failed");
  }
  MatrixXd x = solver.solve(b);
  if(solver.info()!=Success) {
    Rcpp::stop("solving failed");
  }
  return x;
}

/*** R
set.seed(42)
n <- 10000
A <- Matrix::rsparsematrix(n, n, density = 0.2)
b <- matrix(rnorm(n), nrow = n, ncol = 1)
system.time(f <- SparseSolve(A,b))
f[1:4]
*/

结果:

> set.seed(42)

> n <- 10000

> A <- Matrix::rsparsematrix(n, n, density = 0.2)

> b <- matrix(rnorm(n), nrow = n, ncol = 1)

> system.time(f <- SparseSolve(A,b))
   user  system elapsed 
 80.640   0.524  81.163 

> f[1:4]
[1] -1.5994258 -0.6987579  1.3042338  0.1084376