RcppArmadillo:带有each_slice的Lambda表达式

发布于 2025-01-18 10:15:49 字数 904 浏览 3 评论 0原文

我有一个带有正定矩阵的三维阵列,我想获得与所有矩阵的Cholesky因子相同的阵列。我使用的是Armadillo库和Cube类型,其中有方便的函数every_slice我要使用。但是我没有让lambda表达正确地工作,所以希望有人可以帮助我并指出我的错误。

这是一个最小示例:

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

// [[Rcpp::export]]
arma::cube chol_array(arma::cube Sigma) {
  arma::cube Sigma_chol = Sigma;
  Sigma_chol.each_slice([](arma::mat X) {return arma::chol(X);});
  return Sigma_chol;
}
// [[Rcpp::export]]
arma::cube chol_array2(arma::cube Sigma) {
  arma::cube Sigma_chol(size(Sigma));
  for (arma::uword i = 0; i < Sigma.n_slices; i++) {
    Sigma_chol.slice(i) = arma::chol(Sigma.slice(i));
  }
  return Sigma_chol;
}

/*** R
Sigma <- array(crossprod(matrix(rnorm(9), 3, 3)), dim = c(3, 3, 2))
chol_array(Sigma)
chol_array2(Sigma)
*/

函数chol_array2完成作业,但是chol_array只是返回原始矩阵。我想念什么?

I have a three dimensional array with positive definite matrices and I would like to obtain an array of the same size with the Cholesky factors of all matrices. I am using the Armadillo library and the cube type, for which there is the convenient function each_slice which I'm trying to use. But I am not getting the lambda expression to work correctly, so hopefully someone can help me and point out my mistake.

Here is a minimal example:

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

// [[Rcpp::export]]
arma::cube chol_array(arma::cube Sigma) {
  arma::cube Sigma_chol = Sigma;
  Sigma_chol.each_slice([](arma::mat X) {return arma::chol(X);});
  return Sigma_chol;
}
// [[Rcpp::export]]
arma::cube chol_array2(arma::cube Sigma) {
  arma::cube Sigma_chol(size(Sigma));
  for (arma::uword i = 0; i < Sigma.n_slices; i++) {
    Sigma_chol.slice(i) = arma::chol(Sigma.slice(i));
  }
  return Sigma_chol;
}

/*** R
Sigma <- array(crossprod(matrix(rnorm(9), 3, 3)), dim = c(3, 3, 2))
chol_array(Sigma)
chol_array2(Sigma)
*/

The function chol_array2 does the job, but chol_array just returns the original matrices. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眸中客 2025-01-25 10:15:49

这里的问题是 .each_slice()< 中缺少引用/a> 通话。 Armadillo 使用 lambda 表达式需要引用来更新对象,而不是 return 语句。特别是,我们有:

对于表格 3:

将给定的 lambda_function 应用于每个切片; 该函数必须接受对与底层多维数据集具有相同元素类型的 Mat 对象的引用

因此,将:更改

Sigma_chol.each_slice([](arma::mat X) {return arma::chol(X);});

为:

Sigma_chol.each_slice([](arma::mat& X) {X = arma::chol(X);});

固定代码

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

// Enable lambda expressions.... 
// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
arma::cube chol_array(arma::cube Sigma) {
  arma::cube Sigma_chol = Sigma;

  // NOTE: the '&' and saving _back_ into the object are crucial
  Sigma_chol.each_slice( [](arma::mat& X) { X = arma::chol(X); } ); 

  return Sigma_chol;
}

测试代码

set.seed(1113)
Sigma = array(crossprod(matrix(rnorm(9), 3, 3)), dim = c(3, 3, 2))
all.equal(chol_array(Sigma), chol_array2(Sigma))
# [1] TRUE

The issue here is the lack of references in the .each_slice() call. Armadillo's use of lambda expressions require references to update the object and not a return statement. In particular, we have:

For form 3:

apply the given lambda_function to each slice; the function must accept a reference to a Mat object with the same element type as the underlying cube

So, change:

Sigma_chol.each_slice([](arma::mat X) {return arma::chol(X);});

to:

Sigma_chol.each_slice([](arma::mat& X) {X = arma::chol(X);});

Fixed Code

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

// Enable lambda expressions.... 
// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
arma::cube chol_array(arma::cube Sigma) {
  arma::cube Sigma_chol = Sigma;

  // NOTE: the '&' and saving _back_ into the object are crucial
  Sigma_chol.each_slice( [](arma::mat& X) { X = arma::chol(X); } ); 

  return Sigma_chol;
}

Test code

set.seed(1113)
Sigma = array(crossprod(matrix(rnorm(9), 3, 3)), dim = c(3, 3, 2))
all.equal(chol_array(Sigma), chol_array2(Sigma))
# [1] TRUE
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文