使用Rcpp :: IntegerVectors添加int

时间:2013-02-07 21:33:56

标签: c++ r rcpp

这是我在各种情况下遇到的问题的可重现的例子。基本上我有一个C ++ int和一个Rcpp IntegerVector,我想将一个整数添加到另一个整数并将其存储到新的IntegerVector中。数值类型也会出现同样的问题,但现在让它保持整数。

library(inline)

set.seed(123)
x <- sample(1:100,5)

cpp_src <- '
Rcpp::IntegerVector xa = clone(x);
Rcpp::IntegerVector sa(s);
int currentSum = 12; 
std::cout << sa[0] << " ";
std::cout << currentSum << " ";
Rcpp::IntegerVector remainingQuantity = sa[0] - currentSum;
std::cout << remainingQuantity << "\\n";
return remainingQuantity;
'

sumto <- cxxfunction( signature(x="integer", s="integer"), body=cpp_src, plugin="Rcpp", verbose=TRUE )

testresult <- sumto(x=x, s=100L)

这是(灾难性的!)结果:

> testresult <- sumto(x=x, s=100L)
100 12 0x50ebf50
> x
[1] 29 79 41 86 91
> testresult
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[63] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> length(testresult)
[1] 88

我怀疑问题的根源在于我是一个C ++ newb,并且除了C变量类型之外没有一个好的心理模型(即我理解指针,引用和功能级别的解引用) ,但我不知道为什么解除引用IntegerVector似乎在某些地方有效但在其他地方无效,或者std::accumulate返回的数据类型等等。)

无论如何,如果有人可以给我一个关于如何将int添加到Rcpp::IntegerVectors的习语,我们将不胜感激。如果你能解释为什么你发布的解决方案有效,那就更有帮助了。

1 个答案:

答案 0 :(得分:4)

我承认我并不完全确定你的例子是做什么的,但这里有一个变体,使用Armadillo类型。我保留了您的输入向量,并在stdout中显示。

cpp_src <- '
  arma::ivec sa = Rcpp::as<arma::ivec>(x);
  Rcpp::Rcout << sa << std::endl;
  int currentSum = 12;
  Rcpp::Rcout << sa[0] << " ";
  Rcpp::Rcout << currentSum << " ";
  int remainingQuantity = arma::as_scalar(sa[0]) - currentSum;
  Rcpp::Rcout << remainingQuantity << std::endl;
  return Rcpp::wrap(remainingQuantity);
'

armasumto <- cxxfunction(signature(x="numeric", s="integer"), 
                         body=cpp_src, plugin="RcppArmadillo", verbose=FALSE )

testresult <- armasumto(x=x, s=100L)

有了这个,我得到了:

R> cpp_src <- '
+   arma::ivec sa = Rcpp::as<arma::ivec>(x);
+   Rcpp::Rcout << sa << std::endl;
+   int currentSum = 12;
+   Rcpp::Rcout << sa[0] << " ";
+   Rcpp::Rcout << currentSum << " ";
+   int remainingQuantity = arma::as_scalar(sa[0]) - currentSum;
+   Rcpp::Rcout << remainingQuantity << std::endl;
+   return Rcpp::wrap(remainingQuantity);
+ '
R> 
R> armasumto <- cxxfunction(signature(x="numeric", s="integer"), 
+                           body=cpp_src, plugin="RcppArmadillo", verbose=FALSE )
R> testresult <- armasumto(x=x, s=100L)
        29
        79
        41
        86
        91

29 12 17
R> 

为了完整起见,现在我们确定所有内容都在标量上,与Rcpp向量相同:

R> cpp_src <- '
+   Rcpp::IntegerVector xa(x);
+   int currentSum = 12;
+   Rcpp::Rcout << xa[0] << " ";
+   Rcpp::Rcout << currentSum << " ";
+   int remainingQuantity = xa[0] - currentSum;
+   Rcpp::Rcout << remainingQuantity << std::endl;
+   return Rcpp::wrap(remainingQuantity);
+ '
R> newsumto <- cxxfunction(signature(x="integer", s="integer"), 
+                          body=cpp_src, plugin="Rcpp" )
R> testresult <- newsumto(x=x, s=100L)
29 12 17
R>