gpt4 book ai didi

c++ - 尝试使用 RcppArmadillo 编写 setdiff() 函数会出现编译错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:52:42 25 4
gpt4 key购买 nike

我正在尝试使用 RcppArmadillo 在 C++ 中编写 R 的 setdiff() 函数的一种模拟。我相当粗糙的方法:

  // [[Rcpp::export]]
arma::uvec my_setdiff(arma::uvec x, arma::uvec y){
// Coefficientes of unsigned integer vector y form a subset of the coefficients of unsigned integer vector x.
// Returns set difference between the coefficients of x and those of y
int n2 = y.n_elem;
uword q1;
for (int j=0 ; j<n2 ; j++){
q1 = find(x==y[j]);
x.shed_row(q1);
}
return x;
}

编译时失败。错误如下:

fnsauxarma.cpp:622:29: error: no matching function for call to ‘arma::Col<double>::shed_row(const arma::mtOp<unsigned int, arma::mtOp<unsigned int, arma::Col<double>, arma::op_rel_eq>,     arma::op_find>)’

我真的不知道发生了什么,任何帮助或意见将不胜感激。

最佳答案

问题是 arma::find返回 uvec , 并且不知道如何隐式转换为 arma::uword ,正如@mtall 指出的那样。您可以使用模板化的 arma::conv_to<T>::from() 来帮助编译器。功能。此外,我还包含了另一个版本的 my_setdiff返回 Rcpp::NumericVector因为虽然第一个版本返回了正确的值,但它在技术上是一个 matrix (即它有尺寸),我假设你希望它与 R 的 setdiff 兼容。尽可能。这是通过设置 dim 来完成的。返回 vector 的属性 NULL , 使用 R_NilValueRcpp::attr成员函数。


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

// [[Rcpp::export]]
arma::uvec my_setdiff(arma::uvec& x, const arma::uvec& y){

for (size_t j = 0; j < y.n_elem; j++) {
arma::uword q1 = arma::conv_to<arma::uword>::from(arma::find(x == y[j]));
x.shed_row(q1);
}
return x;
}

// [[Rcpp::export]]
Rcpp::NumericVector my_setdiff2(arma::uvec& x, const arma::uvec& y){

for (size_t j = 0; j < y.n_elem; j++) {
arma::uword q1 = arma::conv_to<arma::uword>::from(arma::find(x == y[j]));
x.shed_row(q1);
}

Rcpp::NumericVector x2 = Rcpp::wrap(x);
x2.attr("dim") = R_NilValue;
return x2;
}

/*** R
x <- 1:8
y <- 2:6

R> all.equal(setdiff(x,y), my_setdiff(x,y))
#[1] "Attributes: < target is NULL, current is list >" "target is numeric, current is matrix"

R> all.equal(setdiff(x,y), my_setdiff2(x,y))
#[1] TRUE

R> setdiff(x,y)
#[1] 1 7 8

R> my_setdiff(x,y)
# [,1]
# [1,] 1
# [2,] 7
# [3,] 8

R> my_setdiff2(x,y)
#[1] 1 7 8

*/

编辑:为了完整起见,这里有一个更健壮的版本 setdiff比上面介绍的两个实现:

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

// [[Rcpp::export]]
Rcpp::NumericVector arma_setdiff(arma::uvec& x, arma::uvec& y){

x = arma::unique(x);
y = arma::unique(y);

for (size_t j = 0; j < y.n_elem; j++) {
arma::uvec q1 = arma::find(x == y[j]);
if (!q1.empty()) {
x.shed_row(q1(0));
}
}

Rcpp::NumericVector x2 = Rcpp::wrap(x);
x2.attr("dim") = R_NilValue;
return x2;
}

/*** R

x <- 1:10
y <- 2:8

R> all.equal(setdiff(x,y), arma_setdiff(x,y))
#[1] TRUE

X <- 1:6
Y <- c(2,2,3)

R> all.equal(setdiff(X,Y), arma_setdiff(X,Y))
#[1] TRUE
*/

如果您向它们传递具有非唯一元素的 vector ,例如,以前的版本会抛出错误

R> my_setdiff2(X,Y)

error: conv_to(): given object doesn't have exactly one element

解决问题并更紧密地镜像R的setdiff , 我们只做 xy独特。此外,我关闭了 arma::conv_to<>::fromq1(0) (其中 q1 现在是 uvec 而不是 uword ),因为 uvec只是 uword 的 vector s,显式转换似乎有点不雅。

关于c++ - 尝试使用 RcppArmadillo 编写 setdiff() 函数会出现编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29724083/

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