gpt4 book ai didi

c++ - 作为 S4 对象的一部分返回时避免复制 Armadillo 矩阵

转载 作者:搜寻专家 更新时间:2023-10-31 00:09:29 25 4
gpt4 key购买 nike

我有一个 Rcpp 函数,它接受一个 S4 光栅对象,将一些数据插入一个槽中,然后返回该对象的一个​​新版本。这是一个最小的代表:

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

// [[Rcpp::export]]
Rcpp::S4 new_raster(Rcpp::S4 raster, int n_elem) {
Rcpp::S4 r_data(raster.slot("data"));
r_data.slot("values") = Rcpp::NumericVector(n_elem);

// Need help with...
// creating armadillo vector from `r_data.slot("values")` here
// arma::vec new_data = ... ?

return raster;
}

/*** R
library("raster")
r <- raster(res = 0.1)
n <- ncell(r)
r1 <- new_raster(r, n)
head(r1@data@values)
*/

由于返回的数据可能非常大,我想避免创建多个 vector 拷贝。如何在不复制的情况下在 raster@data@values 槽中创建 Armadillo vector ?

最佳答案

编辑:我没有正确理解问题。目标是从 S4 对象中提取信息,并与 Armadillo 对象共享该内存。我将保留此答案的第一部分,因为它仍然有优点,因为它强调了如何重用 Armadillo 对象内存并重新分配给 NumericVector。不过,考虑到在 Noam 做出回应后问题现在变得清晰起来,第二部分可能更相关。


如果我对问题的理解正确,目标是重用已分配给初始 Armadillo vector 的内存位置(例如零填充)。每个评论的子目标是稍后将其移动到 NumericVector 中。

那么,我们开始吧:

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

// [[Rcpp::export]]
Rcpp::NumericVector vec_mem_ex(int n_elem) {

// Make the initial vector
arma::vec X(n_elem, arma::fill::zeros);

// Create a new vector
arma::vec Y(X.begin(), X.n_elem, false, true);
// `copy_aux_mem` is set to false, the vector will instead directly
// use the auxiliary memory (ie. no copying).
// This is dangerous in certain circumstances!

// `strict` is set to true, the vector will be bound to the
// auxiliary memory for its lifetime; the number of elements
// in the vector can't be changed

// Show memory is shared by modifying value
Y.fill(42.0);

// Convert X to a NumericVector
Rcpp::NumericVector Z = Rcpp::NumericVector(X.begin(), X.end());

return Z;
}

/***R
(a = vec_mem_ex(5))
*/

这给出:

> (a = vec_mem_ex(5))
[1] 42 42 42 42 42

编辑

要捕获问题的 S4 特性并通过@noam-ross 的回答给出更新,请考虑以下事项:

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

// [[Rcpp::export]]
Rcpp::S4 new_raster(Rcpp::S4 raster, int n_elem) {

// Embed S4 object for nesting
Rcpp::S4 r_data(raster.slot("data"));

// Create obj@data@values
// Initializes values with a vector of 0's.
r_data.slot("values") = Rcpp::NumericVector(n_elem);


// --- The new part...

// We do _not_ have access to the vector that was stored in r_data.slot("values")

// Convert from SEXP to NumericVector
Rcpp::NumericVector temp = Rcpp::NumericVector(r_data.slot("values"));

// Use the advanced vector ctor of Armadillo to capture the memory location
arma::vec new_data(
temp.begin(), // Uses the iterator interface to access the double* requirement
n_elem, // Set the size of the vector
false, // Avoid copying by disabling `copy_aux_mem`
true // Bind memory by enabling `strict`
);

// Show memory is shared by modifying value
new_data.fill(42.0);

// --- End new

return raster;
}

/*** R
library("raster")
r <- raster(res = 0.1)
n <- ncell(r)
r1 <- new_raster(r, n)
head(r1@data@values)
*/

关于c++ - 作为 S4 对象的一部分返回时避免复制 Armadillo 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43057444/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com