我正在尝试使用下面的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]
答案 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