Rcpp和R代码之间的结果不一致

时间:2017-05-21 22:26:13

标签: r rcpp

更新 前一个例子很复杂,因此请允许我使用一个更简单的例子,如下所示:

以下是Rcpp代码:

#include <RcppArmadillo.h>
#include <RcppArmadilloExtensions/sample.h>
#include <Rmath.h>
#include <Rcpp.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp ;
using namespace arma;
using namespace std;

// [[Rcpp::export]]  
double chooseC(double n, double k) {
  return Rf_choose(n, k);
}
// [[Rcpp::export]]
double function3(double n, double m, double beta) {
  double prob;
  NumericVector k(m);
  NumericVector k_vec(m);
  if(n<m){prob=0;}
  else{
    if(chooseC(n,m)==R_PosInf){
      k=seq_len(m)-1;
      k_vec= (n-k)/(m-k)*std::pow((1-beta),(n-m)/m)*beta;
          prob=std::accumulate(k_vec.begin(),k_vec.end(), 1, std::multiplies<double>())*beta;
    }
    else{ 
      prob = beta * chooseC(n,m) * std::pow(beta,m) * std::pow((1-beta),(n-m));
    }

  }
  return(prob);
}

以下是R代码:

function4 <- function ( n , m , beta )
{
  if ( n < m )
  {
    prob <- 0.0
  }
  else
  {
    if (is.infinite(choose(n,m))){
      k<-0:(m-1)
      prob <- beta *prod((n-k)/(m-k)*(1-beta)^((n-m)/m)*beta)
    }
    else{
      prob <- beta * choose(n,m) * beta^m * (1-beta)^(n-m)
    }
  }
  prob
}

比较

input<-619
beta<-0.09187495

x<-seq(0, (input+1)/beta*3)
yy<-sapply(x,function(n)function3(n,input, beta=beta))
yy2<-sapply(x,function(n)function4(n,input, beta=beta))
sum(yy)=0
sum(yy2)=1

然而,使用其他输入:

input<-1
beta<-0.08214248

两个结果都相同,sum(yy)=sum(yy2)=0.9865887

我在Rcpp代码中使用double,我不知道还有什么可能导致Rcpp和R代码之间的精度不一致。

非常感谢!

1 个答案:

答案 0 :(得分:0)

我认为我修复了Rcpp代码,所以当结果是非常小的值时,Rcpp和R代码现在都产生相同的结果。解决方案如下所示:

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

using namespace Rcpp ;
using namespace arma;
using namespace std;

// [[Rcpp::export]]  
double chooseC(double n, double k) {
  return Rf_choose(n, k);
}

// [[Rcpp::export]]
double function3(double n, double m, double beta) {
  double prob;
  arma::vec k = arma::linspace<vec>(0, m-1, m);
  arma::vec k_vec;

  if(n<m){prob=0;}
  else{
    if(chooseC(n,m)==R_PosInf){ 
      k_vec= (n-k)/(m-k)*pow((1-beta),(n-m)/m)*beta;  
      prob=arma::prod(k_vec)*beta;
    }
    else{ 
      prob = beta * chooseC(n,m) * pow(beta,m) * pow((1-beta),(n-m));
    }

  }
  return(prob);
}

但是,我仍然不明白为什么以这种方式编写代码会修复精度不一致。 RcppRcppArmadillo对我来说仍然看起来像黑盒子。