L'échantillon () de RcppArmadillo est ambigu après la mise à jour de R

9

Je travaille généralement avec une fonction Rcpp courte qui prend en entrée une matrice où chaque ligne contient K probabilités qui totalisent 1. La fonction échantillonne ensuite au hasard pour chaque ligne un entier entre 1 et K correspondant aux probabilités fournies. Voici la fonction:

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

using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector sample_matrix(NumericMatrix x, IntegerVector choice_set) {
  int n = x.nrow();
  IntegerVector result(n);
  for ( int i = 0; i < n; ++i ) {
    result[i] = RcppArmadillo::sample(choice_set, 1, false, x(i, _))[0];
  }
  return result;
}

J'ai récemment mis à jour R et tous les packages. Maintenant, je ne peux plus compiler cette fonction. La raison n'est pas claire pour moi. Fonctionnement

library(Rcpp)
library(RcppArmadillo)
Rcpp::sourceCpp("sample_matrix.cpp")

renvoie l'erreur suivante:

error: call of overloaded 'sample(Rcpp::IntegerVector&, int, bool, Rcpp::Matrix<14>::Row)' is ambiguous

Cela me dit essentiellement que mon appel à RcppArmadillo::sample()est ambigu. Quelqu'un peut-il m'expliquer pourquoi c'est le cas?

M. Zen
la source

Réponses:

9

Il se passe deux choses ici, et deux parties à votre problème et donc la réponse.

Le premier est "meta": pourquoi maintenant ? Eh bien, nous avons laissé un bug dans le sample()code / setup que Christian a gentiment corrigé pour la version la plus récente de RcppArmadillo (et tout est documenté ici). En bref, l'interface de l'argument très probable qui vous pose problème a été modifiée car elle n'était pas sûre pour une réutilisation / une utilisation répétée . C'est maintenant.

Deuxièmement, le message d'erreur. Vous n'avez pas dit quel compilateur ou quelle version vous utilisez, mais le mien (actuellement g++-9.3) est en fait assez utile avec l'erreur. Il s'agit toujours de C ++, donc une danse interprétative est nécessaire, mais en gros, cela indique clairement que vous avez appelé avec Rcpp::Matrix<14>::Rowet aucune interface n'est fournie pour ce type. Qui est correct. sample()offre quelques interfaces, mais aucune pour un Rowobjet. La solution est donc, encore une fois, simple. Ajoutez une ligne pour aider le compilateur en rendant la ligne a NumericVectoret tout va bien.

Code fixe

#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>

// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector sample_matrix(NumericMatrix x, IntegerVector choice_set) {
  int n = x.nrow();
  IntegerVector result(n);
  for ( int i = 0; i < n; ++i ) {
    Rcpp::NumericVector z(x(i, _));
    result[i] = RcppArmadillo::sample(choice_set, 1, false, z)[0];
  }
  return result;
}

Exemple

R> Rcpp::sourceCpp("answer.cpp")        # no need for library(Rcpp)   
R> 
Dirk Eddelbuettel
la source