2 votes

Ajout d'int avec Rcpp::IntegerVectors

Voici un exemple reproductible d'un problème que j'ai rencontré dans divers contextes. En gros, j'ai un programme C++ int et un Rcpp IntegerVector et j'aimerais simplement ajouter un entier à un autre et le stocker dans un nouveau IntegerVector . Le même problème se pose avec les types numériques, mais restons-en aux entiers pour l'instant.

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)

Et voici les résultats (désastreux !) :

> 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

Je soupçonne qu'à la racine du problème, je suis un débutant en C++ et que je n'ai tout simplement pas un bon modèle mental pour tout ce qui dépasse les types de variables C (c'est-à-dire que je comprends les pointeurs, les références et le déréférencement à un niveau fonctionnel, mais je n'ai aucune idée de la raison pour laquelle le déréférencement d'un IntegerVector semble fonctionner à certains endroits mais pas à d'autres, ou quel type de données std::accumulate retours, etc.).

Quoi qu'il en soit, si quelqu'un pouvait me donner un idiome sur la façon d'ajouter int a Rcpp::IntegerVectors nous vous en serions reconnaissants. Il serait encore plus utile que vous expliquiez pourquoi la solution que vous avez postée fonctionne.

4voto

Dirk Eddelbuettel Points 134700

Je dois admettre que je ne suis pas tout à fait sûr de ce que votre exemple est censé faire, mais voici une variante, utilisant les types Armadillo. J'ai gardé votre vecteur d'entrée, et le montre aussi dans 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)

Avec ça, je comprends :

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> 

Et pour être complet, maintenant que nous avons établi que tout est sur des scalaires, il en va de même avec les vecteurs 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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X