在Rcpp(Eigen)中转换NumericVector / Matrix和VectorXd / MatrixXd以执行Cholesky求解

时间:2013-12-06 23:42:01

标签: r rcpp

编辑:根据Dirk在下面的回答中提供的一些线索,我解决了问题,解决了问题。

我确信这必须在某处记录,但我的谷歌技能让我失望。

我正在开发一个我认为不需要的Rcpp软件包 依赖于Eigen,所以我非常广泛地使用了NumericVector/Matrix。 但是,我现在需要一个Cholesky分解/解决:我知道如何做到这一点 使用RcppEigen,但我需要VectorXd/MatrixXd。说我有一个P.S.D. NumericMatrix,A和NumericVector,b。我尝试了以下各种变化:

  Rcpp::NumericVector b(bb);
  Rcpp::NumericMatrix A(AA);
  Eigen::Map<Eigen::MatrixXd> A_eigen = as<Eigen::Map<Eigen::MatrixXd> >(A);
  Eigen::Map<Eigen::VectorXd> b_eigen = as<Eigen::Map<Eigen::VectorXd> >(b);
  Eigen::LLT<Eigen::MatrixXd> llt(A_eigen);
  Eigen::VectorXd x = llt.solve(b_eigen);
  Rcpp::NumericVector xx(wrap(x));
  return xx;

然后可以使用codeString包编译它(由inline表示),如下所示:

f = cxxfunction(signature(AA="matrix",bb="numeric"),codeString,plugin="RcppEigen")

我知道我可以直接从SEXP实例中获取Eigen::MatrixXd/VectorXd(例如使用Eigen :: Map)但在我的使用中我需要从NumericMatrix / Vector实例获取这些实例。

我的A会很小,所以我也不是 担心是否创建了完整副本。如果有人能提供笨重的话 解决方案,这将是一个很好的,一个优雅的解决方案 太棒了!

提前感谢,也感谢Rcpp(Eigen)的所有伟大工作,

大卫

2 个答案:

答案 0 :(得分:3)

查看RcppEigen来源和文件src/fastLm.hsrc/fastLm.cpp

他们通过多种不同的分解方法建立了一个非常好的工厂。请注意,对于每个实现的解算器,结果始终是受保护的VectorXd m_coef(即特征类型),它仅在最后转换:

        // Copy coefficients and install names, if any
NumericVector     coef(wrap(ans.coef()));
List          dimnames(NumericMatrix(Xs).attr("dimnames"));

可以想象我们可以以不同的方式做到这一点 - 但是这个例子在很长一段时间内都运行良好。我会跟着它。

答案 1 :(得分:-1)

Choleski分解在基础上实施。 Here是文档的链接。如果我误解了,那么也许你自己可以写一个?检查几种语言的Choleski分解的this Rosetta代码链接,为您提供想法。